An Introduction to the Futuristic New Router in AngularJS

Originally published at: http://www.sitepoint.com/introduction-futuristic-new-router-angularjs/

AngularJS is one of the most popular JavaScript MV* frameworks and is widely used to build single-page applications (SPA). One of the challenging features in SPAs is routing. Routing on the client side involves changing a portion of the view and creating an entry in the browser’s navigation history. As a fully featured client-side framework, AngularJS has always had support for routing via the the ngRoute module. Although this is good enough for basic routes, it doesn’t support more complex scenarios, such as nested views, parallel views or a sequence of views.

A new router for Angular 2 is currently in progress and it will be back-ported to Angular 1.4. In this article, we will see how the new router can be used to define routes and how it solves some of the problems that ngRoute couldn’t.

As already stated, work on the new router is still in progress at the time of writing this article and some of the APIs may later change. The Angular team hasn’t thought of a name for the new router yet, so for now it is called the futuristic router.

Limitations of ngRoute

ngRoute was not created with complex enterprise applications in mind. I have personally seen applications where certain portions of a page need to be loaded in several steps. Such applications can be built using ngRoute, but it is almost impossible to have a URL state for every single change applied to the view.

The ng-view directive can be used only once inside an instance of the ng-app directive. This prevents us from creating parallel routes, as we cannot have two parallel views loading at the same time.

The view template to be rendered inside ng-view cannot contain another ng-view directive. This prevents us from creating nested views.

The new router addresses these issues and provides a flexible way of defining and using routes. The new router also embraces the Controller as syntax . I highly recommend using the Controller as syntax, as it is one of the conventions to be followed today to get ready for Angular 2.

Creating Simple Routes

The new router is being created with Angular 2 in mind. Angular 2 will simplify dependency injection by eliminating the module config phase, which means that we don’t need to write a config block to define routes—we can define them anywhere.

Every route to be added to the new router consists of two parts:

  • path: URL of the route’s template
  • component: a combination of a template and a controller. By convention, both controller and template have to be named after the component

Routes are configured with the $router service . As $router is a service, we can define the routes anywhere in the app (other than in a provider or, config block). However, we need to make sure that the block of code defining routes is executed as soon as the app is loaded. For example, if the routes are defined in a controller (as we will do shortly), the controller has to be executed on page load. If they are defined in a service, the service method has to be executed in a run block.

Navigating Between Templates

Let’s define two simple routes and navigate between them using the new router. If you want to follow along with this code, you’ll need to grab a copy of the new router. Show me how.

You can install the new router on a per project basis via npm.

mkdir new-router && cd new-router
npm install angular-new-router

This will create a folder called node_modules in your project directory. The new router can be found at node_modules/angular-new-router/dist/router.es5.min.js. Include it in your project after AngularJS itself.

First off, let’s define a module and configure the routes:

angular.module('simpleRouterDemo', ['ngNewRouter'])
  .controller('RouteController', ['$router', function($router){
    $router.config([
      { path:'/', redirectTo:'/first' },
      { path:'/first', component:'first' },
      { path:'/second/:name', component:'second' }
    ]);

    this.name='visitor';
  }])

The controller in the above snippet defines three routes. Notice that the root route redirects to our first template and that the third route accepts a parameter in the URL. As you see, the syntax of specifying the parameter is same as it is for ngRoute.

As already mentioned, every component requires a corresponding view template and a controller. By convention, the name of controller should be name of the component suffixed with “Controller” (so firstController and secondController in our case). The name of the view template has to be the same as the name of the component. It also has to reside in a folder with the same name as the component, inside a folder named components. This would give us:

projectRoot/
  components/
    first/
      first.html
    second/
      second.html

These conventions can be overridden using $componentLoaderProvider. We will see an example of that later, but for now let’s stick to the conventions.

Next come the views for the components first and second used above. We’re defining them in-line using the ng-template directive (so that we can recreate a runnable demo), but ideally they should be in separate HTML files:

<script type="text/ng-template" id="./components/first/first.html">
  <h3>{{first.message}}</h3>
</script>

<script type="text/ng-template" id="./components/second/second.html">
  <h3>{{second.message}}</h3>
</script> 

As the views are very simple, so are the controllers:

angular.module('simpleRouterDemo')
  .controller('FirstController', function(){
    console.log('FirstController loaded');
    this.message = 'This is the first controller! You are in the first view.';
  })
  .controller('SecondController', function($routeParams){
    console.log('SecondController loaded');
    this.message = 'Hey ' + $routeParams.name + 
      ', you are now in the second view!';
  });

As both of these controllers are created to be used with the Controller as syntax, they don’t accept $scope. The $routeParams service is used to retrieve the values of the parameters passed in the route.

Now, we need to load this controller to have the routes registered:

<body ng-app="simpleRouterDemo" ng-controller="routeController as route">
</body>

Finally, we need to link these routes and load them into the page. The new router brings the ng-link directive and ng-viewport directive, which link views and load templates respectively. The ng-viewport directive is similar to ng-view; it’s a placeholder for part of your app loaded dynamically based on the route configuration.

The following snippet shows the usage of these directives:

<div class="col-md-3">
  <ul class="nav">
    <li>
      <a ng-link="first">First</a>
    </li>
    <li>
      <a ng-link="second({ name:route.name })">Second</a>
    </li>
  </ul>
</div>
<div class="col-md-9">
  <ng -viewport></ng>
</div>

See the Pen Navigating Between Templates with Angular’s New Router by SitePoint (@SitePoint) on CodePen.

Continue reading this article on SitePoint

I know AngularJS always attract a lot of attention, but I often wonder if it’ll be still “cool” in a couple of years due to Aurelia and React.

It is backed by Google. I take solice in knowing that. However, no one can predict the future. Chances are in 5 years time there will be something completely new either way.

I agree that Aurelia and React are great and lately they are getting a lot of attention. It will be too early to say if Angular will be as cool as it is today. We need to wait till Angular 2 and Aurelia reach their stable versions and then watch the war between the two great frameworks!

And still Google doesn’t use it for main projects like Gmail (as far as I know).

Yes, gmail is written using GWT and I don’t think that Google is going to rewrite it using Angular. A few of their apps like Google trends, Doubleclick and some of Google’s Chrome extensions are written using Angular.

That doesn’t stop them from pulling the rug from under you… look what happened with Google Reader.

The same can be said for anything.

“Futuristic New Router” … a.k.a. catching up to industry standards, after several years of a sub-standard router. Definitely one of the weakest points in Angular thus far.

Regarding Angular’s future (vs. X or Y competing framework)… there’ll always be new frameworks. React is hot right now, because it gave us the virtual DOM. Aurelia is hot because it introduces some other new stuff. In 2016, even newer frameworks will emerge … and they will also push the needle forward.

It’s hard for any framework to keep up (hence why Angular 2.0 is essentially a complete rewrite). Folks inevitably jump to newer, hotter ones. Remember Ext JS? SproutCore? YUI? They were prescient for their time, but inevitably grew stale and untenable.

The fact that Angular is maintained by Google means nothing. A team of 100 people can vanish in a day, if some exec decides to put their priorities elsewhere. Frankly, Google derives more benefit from Angular as a recruiting tool (to hire talented UI engineers) than anything else.

I think it’s an overstatement to say that Google maintaining Angular “means nothing”. Yes, a team of 100 can vanish in a day. Or it could NOT vanish, and therefore you have a team of quality developers who are paid to work on that framework, vs. other frameworks that may lack that support. Yes, Google will turn their back on it some day, but it will probably be when it’s deemed obsolete or no longer very relevant. And since it’s open source, is it really any worse off after Google stops working on it that any other framework that already lacks the backing of a company like that? I think what really matters is traction among developers and products. If it’s being used and it’s open source, people will maintain it as long as they need to.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.