Angular 2 — Components and Router + Angular Material

Ashwin Sureshkumar
5 min readJan 24, 2017

My last post shows the setup process for Angular 2 + Angular Material using Angular CLI. In this blog post, we are going to layout the high level component architecture for the app and code the header, router and folder structure for a feature component. Below is high level hierarchal representation of our components (I have prefixed our app components with Hn). As we get more into the hackernews api details we will revisit our components architecture.

Every developer/team splits components in what makes sense to them and there is no one way splitting in component. You can go as granular as you need at to level of a label component in a form or higher level as you see fit.

In the diagram, I have split the components into SmartComponents and PresentationalComponent.

Smart Components or Container Components are components which our tied to applications, interacts with the service and holds the data of that component.

Presentational Components or Dumb Components are pure visual components which gets data passed on to them using @Input. In our app we will keep all our smart components under containers folder under each feature module and presentational components under component unless if its reused then we will create a shared folder, we will see this later.

I have split the app on the top level as HnHeaderComponent and RouterOutlet which will display the components according to the current route of the app. The routes I have planned are mimicking HackerNews.

/newest      -> HnNewestComponent
/shows -> HnShowsComponent
/newcomments -> HnCommentsComponent
/story/:id -> HnStoryDetailsComponent
/ask -> HnAskComponent
/jobs -> HnJobComponent

Then each of the smart component has presentational component under them. Alright lets start coding our components and their hierarchy starting fromHnHeaderComponent.

Open angular-cli.json and change the prefix to hn and styleExt to scss. Lets generate our header component.

ng g component header

This will generate a component with needed files as below

Move our header section from app.component.html and app.component.scss to header.component.html and header.component.scss.

If you check your app.module.ts angular CLI has already imported the Header Components and added to declaration as part of the generator process. The last step is to add the header component to app.component.html

<hn-header></hn-header>

The browser should have reloaded automatically with our changes and you should be able to see the app similar to before our small refactor.

I am splitting each of the major section under the router-outlet as a module. Lets use angular CLI to generate them

ng g module newest
installing component
create src/app/newest/newest/newest.component.scss
create src/app/newest/newest/newest.component.html
create src/app/newest/newest/newest.component.spec.ts
create src/app/newest/newest/newest.component.ts
update src/app/newest/newest.module.ts
mkdir src/app/newest/containersng g component newest/containers/newest
installing component
create src/app/newest/containers/newest/newest.component.scss
create src/app/newest/containers/newest/newest.component.html
create src/app/newest/containers/newest/newest.component.spec.ts
create src/app/newest/containers/newest/newest.component.ts
update src/app/newest/newest.module.ts
  1. Generating a module named newest
  2. Create a directory named containers
  3. Generate a component newest under containers directory

Lets import the newest module in our app. Open up the app.module.ts

// import 
import { NewestModule } from './newest/newest.module';
// add to the imports array in @NgModuleimports: [
BrowserModule,
MaterialModule.forRoot(),
NewestModule
],

Now time to create our routes for the app. We will start with routing to the newest component. Create a file app.routing.ts under the src/app. Refer docs for more detailed configuration.

import { Routes } from '@angular/router';
import { NewestComponent } from './newest/containers/newest/newest.component';
export const routes: Routes = [
{
path: '',
redirectTo: '/newest',
pathMatch : 'full'
},
{
path: 'newest',
component : NewestComponent
}
];

Import defined routes into our app.module.ts

// import 
import { routes } from './app.routing';
import { RouterModule } from '@angular/router';
// imports in @NgModule
```
imports: [
BrowserModule,
MaterialModule.forRoot(),
RouterModule.forRoot(routes),
NewestModule
],

Open app.component.html and add <router-outlet></router-outlet>. This will be location where the router will load the component into.

<hn-header></hn-header>
<router-outlet></router-outlet>

Open header.component.ts and add routerLink for the New nav item.

<li routerLink="/newest">New</li>

We are creating a route newest which loads the NewestComponent. If the app loads with no route specified we are telling the router to redirect it to newest by default. Launch the app with ng serve and go to localhost:4200. You should see the below

In the above screenshot, you can see even though we entered localhost:4200 the app has redirect to localhost:4200/newest as it is our default route specified in the router config. On the right, you can notice that the hn-newest component is loaded below the router outlet. As we add new routes, that will be switched according to the configuration.

In the post, we have covered

  1. High level architecture of our app.
  2. Smart vs Presentational Components
  3. Folder structure for our components
  4. Setup router configuration and router link
  5. Set default route for the app

You can go ahead and setup the routes for the rest of the sections of the nav similarly and verify the navigation between different routes.

In the next post we will see setup for Firebase and getting the newest stories from firebase for HackerNews.

--

--