Angular UI Routing and Components

Angular UI Router has slowly been integrating support for routing to Angular components. This post will discuss why that’s useful, and how to do it using both Angular UI Router 0.x.x and 1.0.0-beta.x versions.


With the introduction of Angular components in version 1.5, the concept of a stand alone, reusable set of behaviors and views became easier to define than previously done in directives. These changes include: abstracting scope, binding to controllers explicitly, providing lifecycle hooks into the controller, as well as a few other things.

This allowed for better componentization of entire views and applications. With that came the realization that a webpage is a component comprised of components.

That being said, routing to a component became a desired behavior.

Smart vs Dumb Components

Before delving into the use of UI Router to route to components, the concept of smart and dumb components should be discussed.

A smart component is one that is very aware of the API and the data driving a view. This means in its controller, it’s typically making a service call upon initialization of the component. It knows what is required to make the call and the response it should expect from the API.

On the other hand, there are dumb components which know what to do with a passed in object or value and what interactions it is responsible for. It typically does not interact with any services. Most interactions result in a callback to a parent component to pass information back up to be used
by a smart component or are related purely to display changes.

For the sake of reusability, dumb components typically are the most reusable (think containers with headers, navigation bars, select boxes, etc). Smart components are great for building full applications from a high level, but they aren’t very customizable.

The best way to make a component dumb is to remove the API calls from the controllers and find a way of providing that data via some sort of binding. This is helpful if you already have the same data that a smart component needs, but don’t want to make two hits to the server for it.

Writing an Application as a Component

With the move to componentized applications, there was mind shift related to how we view applications. Entire applications can be viewed as a component. This actually has practical use cases. For instance, if we write our application as a component, we can take a stand alone web application and potentially put it into a hybrid web container and make a mobile application from it.

The best way to write an application as a component is to take advantage of nested views in UI Router. This can be challenging, at times, but it allows for great flexibility in swapping out components based
on the state of the application.

Use of Components in State Definition using Template

The first integration with routable components was to, instead of using a templateUrl property on the state definition, was to use the template property, instead. An example of this would be as

Obviously, this works, but when each and every state is declared with an HTML element that is simply a single HTML element with no attributes, it starts getting tedious.

Granted, all of the logic and display related to that component is isolated and reusable. If, for instance, you decide to wrap myComponent in a navigation template, you can now do that without having to generate a new component from a template had you set up the same state as such:

Binding to Components

How do we write a full application as a dumb component, when many of our routes need to make service calls to display information that a user wants to view?

One possible answer to this is to resolve the data necessary for the component to function from the route and then bind it into the component via the component’s bindings. There are two approaches to doing this:

  1. Create a smart component that wraps a dumb component. The sole purpose of the smart component is to make a service call and properly bind to the dumb component.
  2. Use the resolve functionality provided in UI router to resolve data directly to the dumb component.

There are some obvious tradeoffs to both options. With a smart component wrapper, you’ve got an additional component to maintain. For resolving to the component using UI router, you’re tying yourself to the router’s ability, and it’s also more difficult to manage exception handling.

That being said, creating routable components via UI Router’s bindings is extremely simple, and UI Router is powerful enough and provides great functionality to the point where, if it’s in your project, it’ll likely remain there until a full rewrite of an application.

Binding to Components — 0.x.x

To bind to a component in the stable release of UI Router (0.x.x), UI Router creates a $resolve object in the context that it used to compile the contents of the ui-view.

This can be used to bind to a component declaration in the template property of the state definition.

This allows us to remove the UserService dependency from the user component. For those smart components that simply make a service call then display the information, we can actually eliminate an entire controller, as well.

Binding to Components — 1.0.0-beta.x

With the release of angular-ui-router@1.0.0-beta.x, the component property was added to the state definition object. This allows for the developer to bind directly to a component as defined on the angular module. It eliminates the need for having a template containing a single element as we had seen in the past.

Please note

Component strings should match how they are registered in their .componentdeclaration, and not dashersized.

In addition, it cleans up the use of a specific keyword to UI Router ($resolve). To do this, it binds directly to the properties defined on the component’s bindingsdefinition. This streamlines the definition:


To wrap things up, an application that is composed purely of components seems to be the direction the web world is going. Angular 1.5 components makes this relatively simple to achieve. In addition, it aligns with where future angular versions are going (i.e. Angular 2). Routable components in an application are very well supported in Angular UI Router both in current stable releases, as well as the beta version available on NPM.

To see an example of the above concepts, please check out this github repo.

Front End Developer