Lesson Weekend

In the last lesson, we created a router to navigate through our pages, and specified that our WelcomeComponent should appear on our homepage. Our welcome page now shows in the browser, but we don't have enough routes in place to test our router. In this lesson, we'll create two more routes for our application: a "Marketplace" page and an "About" page. By the end of the lesson, our application structure will look like this:

route-diagram-3

Adding a New Route

To add a new route to an application that already has a router in place, we need to do the following:

  1. Create a component for the new route, if necessary.
  2. Import the new component into the router file.
  3. Define a new Route object in the router's appRoutes array.
  4. Create a way for users to navigate to the new route.

About Component

First, let's add a route to tie the URL localhost:4200/about to an AboutComponent. We'll start by creating the new component using Angular CLI:

$ ng g component about

Our app directory should now look like this:

src/app
├── app.component.css
├── app.component.html
├── app.component.spec.ts
├── app.component.ts
├── app.module.ts
├── app.routing.ts
│
├── about
│   ├── about.component.css
│   ├── about.component.html
│   ├── about.component.spec.ts
│   └── about.component.ts
│
└── welcome
    ├── welcome.component.css
    ├── welcome.component.html
    ├── welcome.component.spec.ts
    └── welcome.component.ts

Let's open about.component.ts first. It should contain the following:

src/app/about/about.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

Once again, we won't require the ngOnInit method, or OnInit interface. You may either remove them, or leave them blank. We'll remove them for the purposes of this lesson:

online-retail-store/src/app/about/about.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.css']
})
export class AboutComponent {

}

Let's add some HTML to the AboutComponent's template. Feel free to get creative and use your own content.

src/app/about/about.component.html
<h1>About Us</h1>
<p>Epicodus's mission is to help people learn the skills they need to get great jobs. For us, "great jobs" means jobs in growing industries that pay well and provide rewarding work.

Beyond the particular skills needed to get these jobs, we also aim to help our students become confident self-teachers who can adapt to changing job markets and great communicators that will work well in teams. We focus on serving people that, by birth or circumstance, don't have easy access to learning the skills they need to get these great jobs.

And now we sell music too!</p>

Add the Route to the Router

We'll need to define a new route to load our AboutComponent in the router file and create a new entry in the appRoutes array:

app/app.routing.ts
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { WelcomeComponent } from './welcome/welcome.component';
import { AboutComponent }   from './about/about.component';

const appRoutes: Routes = [
  {
     path: '',
     component: WelcomeComponent
   },
  {
    path: 'about',
    component: AboutComponent
  }
 ];

export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

Our new route's path property is about, which means it will be located at localhost:4200/about. Its component is AboutComponent because we want the route to display our AboutComponent to users when they navigate to this route.

It's very important to remember you cannot declare your route URLs with an opening slash. A path property of /about will result in serious errors.

Navigating Between Routes

To link to a new route, we use an <a> tag with a special attribute called routerLink. Including this attribute invokes our router so that it can load the correct component. Here's an example of a routerLink attribute:

<a routerLink="path-from-a-route-in-appRoutes">Link Text</a>

The path included must match the path property from the route entry in the router's appRoutes array.

When we click a routerLink, the router is invoked. The router matches the path from the link to the path of a route in appRoutes and loads the component that corresponds with that path.

Let's include routerLinks in our application. We'll add a navbar so users may easily navigate our site. We'll place the navbar in our root AppComponent so that it will be visible throughout our application.

For the sake of simplicity, we'll use this Bootstrap Navbar Template. You're welcome to format and design your own navbar however you'd like.

We'll add code for our new navbar to the root component's template now:

src/app/app.component.html
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <div class="navbar-header">
      <a class="navbar-brand" routerLink="">Epicodus Tunes</a>
    </div>
    <ul class="nav navbar-nav navbar-right">
      <li><a routerLink="about">About</a></li>
    </ul>
  </div>
</nav>

<div class="container">
  <h1>{{title}}</h1>
  <router-outlet></router-outlet>
</div>

Our new routerLinks are located in these two lines:

src/app/app.component.html
...
   <a class="navbar-brand" routerLink="">Epicodus Tunes</a>
    ...
      <li><a routerLink="about">About</a></li>
...

<a class="navbar-brand" routerLink="">Epicodus Tunes</a> will navigate to our index. When this link is clicked, the router will search its appRoutes array for the route whose path matches the path provided in this link, an empty string "":

src/app/app.routing.ts
...
const appRoutes: Routes = [
  {
     path: '',
     component: WelcomeComponent
   },
...

Once it locates this route, it will load the WelcomeComponent into the <router-outlet></router-outlet> tags.

Similarly, <a routerLink="about">About</a> will navigate to our about route. When clicked, the router will search appRoutes for the about path and then load the AboutComponent in our <router-outlet></router-outlet> tags.

Now we can build and serve our application and successfully navigate between the two routes. We can select "About" from our navbar and see our AboutComponent's content at localhost:4200/about. We can also click "Epicodus Tunes" in our navbar to navigate back to the homepage, where we see our WelcomeComponent's content at localhost:4200.

Marketplace Route

Let's create a route for the 'marketplace' page of our online store. We will follow the same steps:

  1. Create a component for the new route.
  2. Import the component into the router file.
  3. Define a Route object in the router's appRoutes array.
  4. Create a way for users to navigate to the new route.

We'll create our new component:

$ ng g component marketplace

Let's add placeholder content to our MarketplaceComponent's template:

src/app/marketplace/marketplace.component.html
<h2>Marketplace</h2>

<p>All our fine products will be listed here shortly!</p>

Import this component into the router and define a new route in appRoutes:

src/app/app.routing.ts
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { WelcomeComponent } from './welcome/welcome.component';
import { AboutComponent }   from './about/about.component';
import { MarketplaceComponent }   from './marketplace/marketplace.component';

const appRoutes: Routes = [
  {
     path: '',
     component: WelcomeComponent
   },
  {
    path: 'about',
    component: AboutComponent
  },
  {
    path: 'marketplace',
    component: MarketplaceComponent
  }
 ];

export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

We'll add a routerLink to our navbar, so we can navigate to this new route:

src/app/app.component.html
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <div class="navbar-header">
      <a class="navbar-brand" routerLink="">Epicodus Tunes</a>
    </div>
    <ul class="nav navbar-nav navbar-right">
      <li><a routerLink="about">About</a></li>
      <li><a routerLink="marketplace">Marketplace</a></li>
    </ul>
  </div>
</nav>

...

When we serve the application, we can click our "Marketplace" link in the navbar and view the MarketplaceComponent's template at localhost:4200/marketplace:

Make sure to implement multiple routes, routers, and routerLinks in your projects as you continue working in Angular this week. In upcoming lessons we'll tackle our remaining AlbumDetailComponent and discuss the special routing concepts necessary to make this route work for any Album in our store.