Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Using Routes In An Angular TypeScript Application

TwitterFacebookRedditLinkedInHacker News

With Angular development happening in full force, I figured it was time to take a break from Angular 1 and start thinking about what it takes to make the switch over to Angular. Like with most JavaScript powered applications you will have a single page composed of partial routes and views. I previously wrote about how to navigate with the AngularJS UI-Router, but in Angular things are pretty different.

Here we’re going to take a look at using routes and views to navigate within our Angular TypeScript application.

UPDATE 11/11/2016: This article has since been updated to use the stable Angular Router component. The latest version is titled Navigating a Web Application with the Angular Router and will offer the best results. Only use this now obsolete tutorial as a learning booster.

Before going forward, this tutorial assumes you have the necessary Node.js dependencies installed and have at least a basic understanding of writing applications with Angular and TypeScript.

Creating A New Project

Let’s go ahead and start a new Angular project. Create a new directory on your desktop called RouteProject and initialize a new NPM package.json file in it by running the following:

npm init -y

Our project will require various Angular and TypeScript dependencies, all of which can be downloaded via the following commands in your Terminal or Command Prompt:

npm install angular2 systemjs typescript live-server

Inside your package.json file you’re going to want to find the scripts property and replace it with the following:

"scripts": {
    "tsc": "tsc -p src -w",
    "start": "live-server --open=src"
},

This allows us to compile our TypeScript application and watch for changes as well as run a simple local server for testing our application. Because of the --open=src tag we can see that all our source files will be in a src directory at the root of our project.

Inside our project’s src directory we need to create two files. The first file we need to create is tsconfig.json and it should contain the following code:

{
    "compilerOptions": {
        "target": "ES5",
        "module": "commonjs",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": false
    }
}

The above JSON is just configuration data for TypeScript which will be used to compile our code.

The second file we need to create is index.html and it should contain the following code:

<html>
    <head>
        <title>Angular QuickStart</title>
        <script src="../node_modules/systemjs/dist/system.src.js"></script>
        <script src="../node_modules/angular2/bundles/angular2.dev.js"></script>
        <script src="../node_modules/angular2/bundles/router.dev.js"></script>
        <script>
            System.config({
                packages: {'app': {defaultExtension: 'js'}}
            });
            System.import('app/app');
        </script>
    </head>
    <body>
        <my-app>loading...</my-app>
    </body>
</html>

The code here is pretty much just parent declarations. It is responsible for including our JavaScript libraries and importing our main TypeScript file src/app/app.ts for use.

Before going any further take note of the <my-app> tags. We will be defining those tags in the src/app/app.ts file.

Defining Parent Application Logic

Let’s jump right into our main TypeScript file. Open src/app/app.ts and include the following code:

import {
    Component,
    View,
    bootstrap,
    provide
} from "angular2/angular2";

import {
    RouteConfig,
    RouterLink,
    RouterOutlet,
    Route,
    ROUTER_DIRECTIVES,
    ROUTER_PROVIDERS,
    Location,
    LocationStrategy,
    HashLocationStrategy,
    Router
} from 'angular2/router';

import { Default } from './default/default';
import { Page2 } from './page2/page2';

@Component({
    selector: "my-app",
    templateUrl: "./app/app.html",
    directives: [ROUTER_DIRECTIVES]
})

@RouteConfig([
    new Route({ path: "/", as: "Default", component: Default }),
    new Route({ path: "/page2", as: "Page2", component: Page2 })
])

class App {

    router: Router;
    location: Location;

    constructor(router: Router, location: Location) {
        this.router = router;
        this.location = location;
    }

}

bootstrap(App, [ROUTER_PROVIDERS, provide(LocationStrategy, {useClass: HashLocationStrategy})]);

So what exactly is the above monster doing?

import {
    Component,
    View,
    bootstrap,
    provide
} from "angular2/angular2";

import {
    RouteConfig,
    RouterLink,
    RouterOutlet,
    Route,
    ROUTER_DIRECTIVES,
    ROUTER_PROVIDERS,
    Location,
    LocationStrategy,
    HashLocationStrategy,
    Router
} from 'angular2/router';

First off we’re injecting both our Angular dependencies and then the Route dependencies that we plan to use. Yes, Route has a lot of dependencies, more than I would hope for, but at this time it is what’s necessary.

import { Default } from "./default/default";
import { Page2 } from "./page2/page2";

Above we’re importing two views that we plan to use for routes. We haven’t created them yet, but at least they will be ready for navigation when we do. The two views will be a default page and then some secondary page.

@Component({
    selector: "my-app",
    templateUrl: "./app/app.html",
    directives: [ROUTER_DIRECTIVES]
})

Here we are defining our application component. Remember in the src/index.html file we made use of the <my-app> tags? This is where we crafted it and anything in this src/app/app.ts file will be injected into them. We’re also defining a template of HTML code which we’ll see next.

@RouteConfig([
    new Route({ path: "/", as: "Default", component: Default }),
    new Route({ path: "/page2", as: "Page2", component: Page2 })
])

In the above snippet we are defining the two routes. Earlier in the file we included the route files, but now we’re defining how these files will be rendered. When a user hits the / endpoint the Default component will be shown. When the user hits the /page2 endpoint the Page2 component will be shown.

Finally we are creating our application class and bootstrapping it.

Creating Our Parent Application View

Now let’s circle back to that ./app/app.html file I told you about earlier. This is going to be our parent template and navigation file. It contains the following source code:

<a [router-link]=["/Default"]>page 1</a> | <a [router-link]=["/Page2"]>page 2</a>
<router-outlet></router-outlet>

The above template code is nothing magical. It serves its specific purpose. Show two links for navigating between routes and then host a router-outlet for containing the child views. This is similar to the <div ui-view> tags from Angular 1.

Creating Our Default Child View

With the application level stuff out of the way, let’s take a look at the two views that we’re going to route to. Starting with the default view, go ahead and create a src/app/default directory. In it you’ll have a src/app/default/default.ts and src/app/default/default.html file.

The src/app/default/default.ts file will contain the following source code:

import {Component, View} from "angular2/angular2";

@Component({
    selector: 'default'
})

@View({
    templateUrl: 'app/default/default.html'
})

export class Default {
    constructor() {

    }
}

Nothing fancy here. We are just naming our component and determining where our HTML template will be stored. Now crack open the HTML file that goes with it and add this code:

<h1>This is the default page</h1>

Again, nothing fancy.

Creating Our Secondary Child View

Now we can work on our second and final route. Create a src/app/page2 directory with src/app/page2/page2.ts and src/app/page2/page2.html in it. I’m sure you can see the trend now.

Starting with the TypeScript file, include the following code:

import {Component, View} from "angular2/angular2";

@Component({
    selector: 'page2'
})

@View({
    templateUrl: 'app/page2/page2.html'
})

export class Page2 {
    constructor() {

    }
}

Pretty similar to what we did in the default route. Open your HTML file and add the following short line of code:

<h1>This is a second page</h1>

At this point in time our application is complete!

Testing The Application

With the project root as your current working directory in your Command Prompt or Terminal, execute the following:

npm run tsc

Since we have the command watching for changes, go ahead and open another Command Prompt or Terminal and run this:

npm start

If it didn’t already do this for you, open a web browser and navigate to http://localhost:8080/src/ to test out the application.

Conclusion

Although not difficult, it did take a bit of effort to be able to route to different views in our Angular application. This allows us to have a single page application like what we had in AngularJS with the UI-Router. Working with partials and routes is incredibly convenient when developing front-end applications. It reduces the amount of code you use and typically makes your project more organized and efficient.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.