How to use AngularJS Component Router with TypeScript?

AngularJS version 1.5 introduced Components that is very useful and provides the best of both controllers and directives. In this post, I’ll tell you how to use AngularJS Component Router with TypeScript that will help you to write better components. Make sure that you know the basics of using component before reading this post.

Scope

The scope of this post is to illustrate how to use ngRoute/ui-router module with component and component router with component. I’ll be reusing the component that I created in post linked above for the rest of this post. If you follow the previous and this post, you will have this end result.

Angular Component Router Demo

Angular Component Router Demo

What is Routing?

Routing is a very important part of your web application as you can change a whole view or parts of a view based on changes in URL.

What are the router options available in Angular?

There are few options available when it comes to routing in Angular, namely: ngRoute, ui-router and component router. ngRoute module is available out of the box in the framework and ui-router is an 3rd party module. Component router was introduced in version 1.5.

How to use ngRoute/ui-router module with angular component?

If you are using ngRoute or ui-router module in your app and would like to use component, you can still activate a component based on a url hash fragment or a state. The trick is to use the template binding and render a component directive. I’ll be using the component from my previous post to illustrate this in code snippet below:

Make sure you have proper router module script added to your document. I’m using ngRoute above in a module named app. The snippet uses template property to specify component directive. reviewList is the component that I created in my previous post and appAbout is another easy component that I added just to illustrate routing. Its implementation is mentioned below and it just has a hard-coded content defined using template property:

Above knowledge is useful when you app is already using a routing module and you want to combine it with the new angular components.

Component Router

Component Router is quite interesting. It is compatible with Angular 2. It also provides useful life-cycle hooks that I’ll explain later in this post. Even nested routing can be used with component router for which I’ll write another post soon. Nested routing is a concept that is not available in ngRoute module but is present in ui-router module. Another important concept is link generation that I’ll explain in this post.

To use any angular module, first requirement is to add script source. Component router can be found from this repository.

Next step is to add this module as a dependency to your own angular module. When this router module is injected, it knows that it needs to look at $routerRootComponent service to instruct about the top-level component that will have all the navigation rules as mentioned below:

That also means, we need to write another component named reviewApp and includes the source file reference in the HTML document. I’ve created review-app.component.ts and review-app.component.html files. Implementation for both is mentioned below:

The component above defines $routeConfig which is quite similar to defining routes using other route modules discussed above. For a matching path, we instruct it to render a component. We can also define an otherwise route so that if a requested route doesn’t exist, then redirect to some other route. name member in the definition is very important as it is used with redirectTo as well as for link generation – that I’ll explain soon.

Let us look at the html document source below that is linked with this component via a templateUrl. So, when this top-level component is requested, the above HTML is rendered.

It shows to use anchor tags for routing with component router in two ways, using #/path and ng-link=['name']. The latter one is the concept of link generation where it matches the name member of routes. If one is found, it then uses the path member’s value to add href attribute to the anchor element as shown above.

Using ngLink directive to reference a route with its name is good so that if in case you change the path for your route, you will just need to change in the configuration and all the references will still use name member’s value. So, it is good for maintenance.

The other directive to note is ngOutlet which is similar to native ngView which works as a placeholder for other views.

Component Router with Parameters

Line no. 8 in the component definition above illustrates how to define a route that any parameter(s). The path is /details/:id which instructs that id will be a dynamic value. This syntax is also used in other router modules. As you can see it also consumes a new component named reviewDetails with a unique name.

Just to link reviewDetails component with our component from previous post, add a link to following to review-list.component.html source which can allow user to see details of a review:

Before looking at reviewDetails component’s implementation, let us discuss the life-cycle hooks that component router provides:

  • $canActivate: if provided, the router will call this to control the navigation from one route to another. It can return either true or false. Example: this can be used to decide a check user’s authentication or authorization whether they are allowed to reach a component or not.
  • $routerOnActivate: use this hook to get to the next and previous route to get any parameters passed.
  • $routerCanDeactivate: if provided, the router will call this to control the navigation. It can return either true or false.
  • $routerOnDeactivate: called by the Router before destroying a Component as part of a navigation.
  • $routerCanReuse: called to determine whether a Component can be reused across Route Definitions that match the same type of Component, or whether to destroy and instantiate a new Component every time.

Let us know look at reviewDetails component’s implementation that uses two of the above hooks. I’ve added two files, namely review-details.component.ts and review-details.component.html that looks like this:

The component uses a template, controller and $canActivate lifecycle hook. When this method was defined using function member, this event was not getting called at all as it is then defined as a prototype member like ReviewDetailsComponent Home Page.prototype.$canActivate. Thus, I’m using lambda expression to define it.

You can inject any service in this like $http or $timeout or your custom service. I’m using $timeout service that mimics a service call to the server that responds a boolean after few seconds. When this returns true, the component’s controller is then instantiated.

The component’s controller then uses another hook named $routerOnActivate event. The next and previous both hold the parameters if they were passed. So, we can get the id parameter from next and can use this to query a record either from cache or server and show it on the UI via view.

So, when user clicks on anchor element that uses ng-link="['Details', { id: review.id }]", the user is then presented with the details view. As Details name is linked with reviewDetails component and the id of selected review is passed as well.

How to navigate from code?

The directive ngLink and href attribute will not help if you would like to navigate from code. Look at the updated HTML source forreview-list.component.html. The code now has a button element that uses a custom method on controller named goTo that takes an id value. Basically, we now just need to use the $router service to navigate to Details route. The updated review-list.component.ts is mentioned below:

Line no. 42 defines goTo method that internally uses $router service’s navigate method. But where does this new service instance comes from? Look at the component’s bindings definition on line no. 55 in the code above, where it asks angular to input this service instance so that it is available to the controller.

Hope, this post explains how to use AngularJS Component Router with TypeScript. I’ll be writing another post about nested routing with Components soon. Keep reading this space to learn more about AngularJS and TypeScript.

Siddharth Pandey

Siddharth Pandey is a Software Engineer with thorough hands-on commercial experience & exposure to building enterprise applications using Agile methodologies. Siddharth specializes in building, managing on-premise, cloud based real-time standard, single page web applications (SPAs). He has successfully delivered applications in health-care, finance, insurance, e-commerce sectors for major brands in the UK. Other than programming, he also has experience of managing teams, trainer, actively contributing to the IT community by sharing his knowledge using Stack Overflow, personal website & video tutorials.

You may also like...

Advertisment ad adsense adlogger