Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Typescript

Build an Angular 2 Earnings Tracker in TypeScript – Part 1

1.44/5 (2 votes)
6 Mar 2017CPOL6 min read 6.5K  
This is the first part of building an Earnings Tracker using Angular and TypeScript Series.

This is the first part of building an Earnings Tracker using Angular and TypeScript Series.

The source code for this tutorial series is published on GitHub. Demo application is hosted in Microsoft Azure.

Part 1: Create an Angular SPA in TypeScript

In the previous tutorial series, we created the Earnings Tracker Web API in ASP.NET Core. In this tutorial, we will use Visual Studio Code to build the initial structure of the Angular Single-Page Application (SPA) in TypeScript.

Client-Side Technologies

The application structure, styles, and patterns follow the recommendations outlined in the official Angular Style Guide.

I use the official Angular Developer Guide as a reference to write this tutorial series.

Prerequisites

The following are required to complete this tutorial:

  • Build the QuickStart app if you are new to Angular
  • Install Node.js and npm (Nods.js > 6.3.x and npm > 3.10.x) on your machine if you haven’t done so already

Task 1. Set up the Project Structure

I prefer to organize my project based on components/modules. Building a maintainable, scalable, and well-organized application should start from the beginning. Using DRY and SRP patterns, we will create smaller code files that each handle one specific job. This approach has helped me personally to locate, enhance, and debug requested features from clients quickly.

  1. Let’s creating folders and copying files to C:\_tutorials\angular-earnings-tracker from GitHub as listed below:

    angular-earnings-tracker                // Project folder      
        |--api                              // test data
            |--dashboard.json   
            |--settings.json
        |--app
            |--dashboard                    // Dashboard feature module
            |--navbar                       // Navbar component
            |--settings                     // Employees feature module
        |--content                          
            |--css
                |--animate.css
                |--keen-dashboards.css
                |--loading-bars.css
                |--styles.css
            |--images
                |--favicon.ico
                |--loading-bars.svg
            |--js
                |--loading-bars.js
        |--package.json
        |--systemjs.config.js
        |--tsconfig.json
  2. Lines 20-22 list the package definition and configuration files:

    • package.json: defines scripts and serves as documentation for what packages the Earnings Tracker depends on.
    • systemjs.config.js: loads application and library modules.
    • tsconfig.json: is a configuration file to guide the TypeScript compiler as it generates JavaScript files.

Task 2. Install the Packages

Open the terminal window, enter the npm install command to install all listed packages and libraries in package.json using npm.

Task 3. Create startup page

  1. Add the index.html file to the angular-earnings-tracker folder.

  2. Replace the code in this file with the following:

    <html>
      <head>
        <base href="/">
        <title>Angular Earnings Tracker by Cathy Wun</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        
        <!-- 1. Load css -->
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" >
        <link rel="stylesheet" href="content/css/animate.css" >
        <link rel="stylesheet" href="content/css/loading-bars.css" >
        <link rel="stylesheet" href="content/css/keen-dashboards.css">
        <link rel="stylesheet" href="content/css/style.css">
    
        <!-- 2. Load libraries -->
        <!--    2.1 Polyfill(s) for older browsers -->
        <script src="node_modules/core-js/client/shim.min.js"></script>
        <script src="node_modules/zone.js/dist/zone.js"></script>
        <script src="node_modules/reflect-metadata/Reflect.js"></script>
        <script src="node_modules/systemjs/dist/system.src.js"></script>
        <!--    2.2 Vendor js libraries -->
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    
        <!-- 3. Configure SystemJS -->
        <script src="systemjs.config.js"></script>
        <script>
          System.import('app').catch(function(err){ console.error(err); });
        </script>
      </head>
    
      <body class="application">
        <!-- 4. Display the application -->
            <earnings-tracker-app>
                <!-- Show simple splash screen-->
                <div class="splash">
                    <div class="color-line"></div>
                    <div class="splash-title">
                        <h1>Angular Earnings Tracker</h1>
                        <img src="content/images/loading-bars.svg" width="64" height="64" title="" alt="" />
                    </div>
                </div>
            </earnings-tracker-app>
      </body>
    </html>

    The index.html file serve as our startup page. It performs the following functions:

    • loads our resources (.css and .js)
    • configures SystemJS to load library modules and launch our application by running the AppModule in the main.ts file
    • renders our application’s component between the earnings-tracker-app tags
    • shows our splash screen

Task 4. Bootstrap our application

  1. Add the main.ts file to the app folder.

  2. Replace the code in this file with the following:

    // Main entry point
    // The browser platform with a compiler
    import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
    
    // The app module
    import {AppModule} from './app.module';
    
    // Compile and launch the module
    platformBrowserDynamic().bootstrapModule(AppModule);

    Line 9 bootstraps the imported AppModule from app.module.ts file using the Just in Time (JIT) complier to launch the application.

Task 5. Create the root module

By convention, every Angular app has a root module class called AppModule in app.module.ts file. The @NgModule decorator allows us to bundle components, services, pipes, and directives at the module level. If you want to learn more about the benefits of using @NgModule, please check out Rob Wormald's blog post.

  1. Let’s add app.module.ts file to the app folder.

  2. Replace the code in this file with the following:

    import { NgModule }         from '@angular/core';
    import { BrowserModule }    from '@angular/platform-browser';
    import { HttpModule }       from '@angular/http';
    
    /* App Root */
    import { AppComponent }     from './app.component';
    import { NavbarComponent }  from './navbar/navbar.component';
    
    /* Feature Modules */
    import { DashboardModule }  from './dashboard/dashboard.module';
    import { SettingsModule }   from './settings/settings.module';
    
    /* Routing Module */
    import { AppRoutingModule } from './app-routing.module';
    
    @NgModule({
      imports:      [ BrowserModule,
                      HttpModule,
                      DashboardModule,
                      SettingsModule,
                      AppRoutingModule
                    ],
      declarations: [ AppComponent, NavbarComponent ],
      bootstrap:    [ AppComponent]
    })
    
    export class AppModule { }
  3. Lines 17 – 22 import the following supporting modules whose exported components, directives, or pipes are referenced by the component declared in the AppModule.

    • BrowserModule: provides critical services that are essential to launch and run our app in the browser
    • HttpModule: provides http services
    • DashboardModule: provides collections of Dashboard functionality
    • SettingsModule: provides collections of Settings functionality
    • AppRoutingModule: is a routing module which provides the top level application-wide configured services with routes in the root module
  4. Line 23 declares a list of components (AppComponent, NavbarComponent) that belong to the AppModule.

  5. Line 24 bootstraps the root component named AppComponent when Angular starts the application.

  6. Line 27 exports the AppModule so that the main.ts file can import it.

Task 6. Configure routes for the Router

The application will have a routing module named AppRoutingModule. It serves as a central place to maintain top level application routing configuration.

Most developers should always implement a Routing Module for the sake of consistency. It keeps the code clean when configuration becomes complex. It makes testing the feature module easier. Its existence calls attention to the fact that a module is routed. It is where developers expect to find and expand routing configuration.
Angular

To learn more about Routing & Navigation, please see the official documentation here.

  1. Add the app-routing.module.ts file to the app folder.

  2. Replace the code in this file with the following:

    import { NgModule }             from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    
    export const appRoutes: Routes = [
        // 1st Route
        { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
        // 2nd Route
        { path: '**', redirectTo: '/dashboard' }
    ];
    
    @NgModule({
      imports: [RouterModule.forRoot(appRoutes, { useHash: true} )],
      exports: [RouterModule]
    })
    
    export class AppRoutingModule {}
  3. Lines 4 – 9 configure our Router with two routes:

    • 1st Route: when initial relative URL is empty (for example: http://localhost:3000) , redirect to another route whose path segment is /dashboard
    • 2nd Route: when URL doesn’t match any routes defined in our configuration, redirect to another route whose path segment is /dashboard
  4. Line 12 uses RouterModule.forRoot method to register two routes with the Router.

  5. Line 13 re-exports the RouterModule by adding it to the module exports array. Since we imported AppRoutingModule with the root module named AppModule, the components declared in AppModule will have access to router directives.

  6. Line 16 exports the AppRoutingModule so that the AppModule in app.module.ts file can import it.

Task 7. Create our root component and its view

  1. Add the root component named app.component.ts file to the app folder.

  2. Replace the code in this file with the following:

    import { Component } from '@angular/core';
    
    @Component ({
        selector: 'earnings-tracker-app',
        templateUrl: 'app/app.component.html',
    })
    
    export class AppComponent {}

    The AppComponent is our application shell.

  3. Add the view named app.component.html file to the app folder.

  4. Replace the code in this file with the following:

    <!-- Navigation Area -->
    <et-navbar></et-navbar>
    <!-- End Navigation Area -->
    
    <!-- Content Area -->
    <div class="container-fluid">
        <!-- Routed View -->
        <router-outlet></router-outlet>
    </div>
    <!-- End Content Area -->

    The app.component.html file contains the master layout for our HTML. It provides a shell with two regions: a navigation area and a content area. The navigation area renders the navbar view between the et-navbar tags. The content area uses router-outlet directive to display the views produced by the Router. In other words, when you click a navigation link, it’s corresponding view is loaded in the content area.

Task 8. Create the Navbar component and its view

  1. Add the navbar.component.ts file to the navbar folder.

  2. Replace the code in this file with the following:

    import { Component } from '@angular/core';
    
    @Component ({
        selector: 'et-navbar'
        ,templateUrl: 'app/navbar/navbar.component.html'
    })
    
    export class NavbarComponent {
        heading = 'Angular Earnings Tracker';
    }

    The navigation area of the AppComponent uses et-navbar to display the navbar view.

  3. Add the view named navbar.component.html file to the navbar folder.

  4. Replace the code in this file with the following:

    <div class="navbar-nav navbar-inverse navbar-fixed-top" role="navigation">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" routerLink="/dashboard" routerLinkActive="active">
                    <span class="glyphicon glyphicon-chevron-left"></span>
                </a>
                <a class="navbar-brand" routerLink="/dashboard" routerLinkActive="active">{{heading}}</a>
            </div> 
        </div>
    </div>

    The navbar.component.html uses Bootstrap for quick styling and building responsive layouts. It uses routerLink directive to represent navigation menu items.

  5. We have the following links in navigation menu:

    • <
    • Angular Earnings Tracker

    Clicking Nav Bar

    When you click either the < or the Angular Earnings Tracker link in the navigation menu, the Dasboard view will be placed in the content area of the AppComponent view:

    Activating Dashboard Feature Module

In the next tutorial, we will build the Angular Dashboard Feature Module using TypeScript.

The source code for this tutorial series is published on GitHub. Demo application is hosted in Microsoft Azure.

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)