Angular Fundamentals: Routing and Navigating Pages

Kevin O'Shaughnessy
5 min readAug 10, 2019

--

Welcome back to this review of the Pluralsight course Angular Fundamentals by Jim Cooper and Joe Eames.

This article is part of a series of reviews of the Angular Learning Path.

All of the modules in this course so far have been presented by Jim Cooper, and he continues to dispense his wisdom here too. Still no sign of Joe yet.

Jim begins by outlining the module and explaining why routing is necessary. Fortunately for us, Angular makes routing relatively simple.

Adding Multiple Pages to Your App

Here Jim creates an event-details component. We don’t need a selector property because the event details component will be routed to from another page, however we do set the templateUrl

This is all done manually in the clip, but the Angular CLI makes generating these things quicker and easier. For details see John Papa’s course.

Jim imports our EventService into this component, and creates an OnInit lifecycle hook which calls this event service, passing in a numeric id argument.

Adding Your First Route

In our event app component we’ve been displaying our event list component as part of the template:

<event-list></event-list>

Now we swap this out for a call to the router outlet:

<router-outlet></router-outlet>

Jim also writes in routes.ts, defining the appRoutes as an array of path objects. In this file, we import the Routes service and make appRoutes implement this. We see that this gives us IntelliSense which helps us avoid typos and other mistakes.

We also need to update app.module.ts, importing the RouterModule and including it in out imports array.

At the end of this clip we see the app redirects from the root of the site to /events and that we can go to the event details page by navigating to events/1

Unfortunately any other id takes us to the same event details page. This is because we just hard-coded the id in our event details component! We see how to do this properly next.

Try the practice exercise.

Accessing Route Parameters

In our event details component we learn how to pull the event id off of the URL.

The first step is to import ActivatedRoute into our component and inject it into the constructor. Once there, we can use the activated route parameter in our NgOnInit method.

Try the practice exercise.

Linking to Routes

Up to now, we’ve been having to manually enter the parameter ids into the URL to move around. Jim shows us how we can move to the event details screen when we click on the relevant event.

Try the practice exercise.

Navigating from Code

Jim creates a simple create-event component.

It has an inline template with submit and cancel buttons. Jim will be enhancing this in the forms module later in this course.

We see the page displays but the cancel button doesn’t do anything. We want it to take us back to the events list page. We can achieve this by adding a click handler in our template, and defining a cancel function in our component.

This also involves importing the Router service and injecting it into the component constructor.

Try the practice exercise.

Guarding Against Route Activation

If we go to an event detail screen where the event doesn’t exist, for example events/42 when no event 42 exists, then we see the screen without any event details, which is not want we want.

Instead we can go to a 404 page. First Jim adds a 404 component.

Then we create event-route-activator.service.ts and this implements the CanActivate interface. In this canActivate function we redirect to a 404 if the event does not exist.

We update app.module.ts, adding our new EventRouteActivator as a provider.

And finally, we update routes.ts, adding a canActivate property which is set to [EventRouteActivator].

Try the practice exercise.

Guarding Against Route De-activation

Sometimes we may want to warn a user if they try to navigate away from a page before saving data, for example. We can do this in Angular with a Deactivator Route Guard.

We use the CanDeactivate interface. Wheareas we created a new service for route activation, we can just use a basic function for our deactivation, and here we call this checkDirtyState.

Jim initially sets this to always return false, and we see this has the effect of disabling all navigation away from our page.

Jim adds an isDirty property to the CreateEventComponent, and passes the component into the checkDirtyState function.

We use the isDirty property to determine whether we immediately navigate away when the user clicks the cancel button, or see a confirmation dialog appear.

Try the practice exercise.

Pre-loading Data for Components

In this clip we use an RxJS observable.

In a later module in this course, Joe Eames talks about observables in much more detail, but for now we can get by with the basics, and Jim gives a simple explanation here.

As a demonstration we create an artificial delay of two seconds before some of the screen is rendered. Sometimes we want to render everything in a component on screen together, and we can use a resolve route handler to do this.

This new service uses the map function from rxjs/operators.

At the end of this clip, we see that we also get the benefit of data caching giving our app a major performance boost!

Try the practice exercise.

Styling Active Links

We want to highlight the currently active link in our navigation bar. We can do this using the router link active directive.

We see that this activates too often and we can fine tune the behavior using routerLinkActiveOptions and setting {exact:true}

Lazily Loading Feature Modules

Big sites can be broken down into smaller sections.

In this clip, Jim starts by creating a new user module which imports the CommonModule and RouterModule. Then he creates user.routes.ts.

For the lazy loading, this is setup in our main routes.ts file. We use loadChildren.

After this is implemented, Jim opens the devtools network tab to show us the feature module is loaded lazily, giving our site another performance boost.

Organizing Your Exports with Barrels

Our app module has a long list of imports. We can tidy up this code by using “barrels”.

This involves creating an index.ts file for each area of the application and exporting from each of them.

Once we have created our “barrels”, in our app.module.ts file we can have a single import statement of all components per barrel.

Thanks very much for reading this article.

The next module in this Angular Fundamentals course is:
Collecting Data with Angular Forms and Validation

--

--

Kevin O'Shaughnessy

Sr. Full Stack Web Dev promoting better professional practices, tools, solutions & helping others.