Angular2 first steps

This post is meant for those who want to start developing with angular 2 and don’t have any experience yet. Don’t worry, we got you.

It is important that you know that all this information is based on Angular documents.
The main idea here is to create a simple application, a basic time tracker that allows workers to log in their time sheets. Are you ready? Let’s go.

timetracker

Official source: angular quickstarter. If you need more information please follow this link

Let’s get started.

To begin with, we have to clarify athat Angular 2 is based on components. Each component is in charge of a portion of the screen, and it is a class and an html.
All classes are implemented with typescript. We are not going to go deep in to that, but if you want to learn more please follow this link

Project folder architecture.

This sample has two main sections, one for login and other one for private. The Public components are in components folder and Private components are in private folder. There is a shared folder that we use to have models and other stuff.

app
---assets
--- components
------ login
------ main
------ pageNotFound
--- private
------ components
--------- header
--------- main
--------- project
--------- timesheet
--------- user
--- shared
------ models
--- styles
--- app.module.ts
--- main.ts
mocks
--- users.json
--- projects.json
node_modules
index.html
package.json
system.config.js
tsconfig.json

All applications must have at least one component, in our case the root module is AppModule. In these we import their modules, we configure the application routes and some other stuff.
NgModule is a decorator where you define the metadata objects whose properties describe the module.
For this demo we only define import, declaration and bootstrap.

  • declarations – the view classes that belong to this module.
  • imports – other modules whose exported classes are needed by component templates declared in this module.
  • bootstrap – the main application view, called the root component, that hosts all other app views. Only the root module should set this bootstrap property.
import { NgModule }      from '@angular/core';
import { FormsModule }   from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, Routes } from '@angular/router';
import { MainPrivateComponent }  from './private/components/main/main.private.component';
import { MainComponent }  from './components/main/main.component';
import { HeaderComponent }  from './private/components/header/header.component';
import { PageNotFoundComponent } from './components/pageNotFound/pageNotFound.component';
import { LoginComponent } from './components/login/login.component';
import { UserListComponent } from './private/components/user/list/user.list.component';
import { UserDetailComponent } from './private/components/user/detail/user.detail.component';
import { ProjectListComponent } from './private/components/project/list/project.list.component';
import { TimesheetComponent } from './private/components/timesheet/timesheet.component';

import { HttpModule, JsonpModule } from '@angular/http';

const appRoutes: Routes = [
    { path: 'login', component: LoginComponent},
    { path: '',   redirectTo: '/login', pathMatch: 'full' },
    { path: 'private', component: MainPrivateComponent,
        children: [
            {path: 'user/:id', component: UserDetailComponent},
            {path: 'users', component: UserListComponent},
            {path: 'projects', component: ProjectListComponent},
            {path: 'timesheet', component: TimesheetComponent}
        ]
    },
    { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [
      BrowserModule,
      RouterModule.forRoot(appRoutes),
      HttpModule,
      JsonpModule,
      FormsModule
  ],
  declarations: [ MainComponent, MainPrivateComponent, HeaderComponent, PageNotFoundComponent, LoginComponent, HeaderComponent, UserListComponent,
                ProjectListComponent, UserDetailComponent, TimesheetComponent],
  bootstrap:    [ MainComponent]
})
export class AppModule { }

How to run the application

Here we give you an example of the main file that bootstraps our application. In our case it is main, if you take a look we are boostraping AppModule.
This main file is loaded with system.js. We will talk about systemjs in future blogs.

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule }              from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

Components

We are not going to explain all components,  we are going to focus on a single one for now:  users component.
The following image is the components structure, if you take a look, we have two components: detail and list. These components use a common service, in this case UserService component.

user
--- detail
------ user.detail.component.html
------ user.detail.component.ts
--- list
------ user.list.component.html
------ user.list.component.ts
--- user.service.ts

Service

In this srvice we have two methods, get to obtain the user and list to get all users.
If you take a look at the code we use Observable, and we take advantage of this using map over the Observable. This is one of the advantage over using promises. we are not going to go further on that, but if you are interested in that please follow this link

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable }     from 'rxjs/Observable';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class UserService {

    constructor(private http: Http){
    }

    public list():Observable<Array>{
         return this.http.get("/mocks/users.json")
                    .map((res:Response) => res.json())
                    .map((res:any) =>{
                        return res.users;
                    })
                    .catch((error:any) =>
                        Observable.throw(error.json().error || 'Server error')
                    )
    }

    public get(id: number): Observable{
        return this.http.get("/mocks/users.json")
            .map((res:Response) => res.json())
            .map((res:any) =>{
                var user = res.users.filter((user:any) => user.id == id);
                return user[0];
            })
            .catch((error:any) =>
                Observable.throw(error.json().error || 'Server error')
            )
    }
}

To list components is really simple, it subscribes to list Observable service and bind the response to users property.

import { Component } from '@angular/core';
import { OnInit } from '@angular/core';
import { UserService } from '../user.service';

@Component({
  templateUrl: './app/private/components/user/list/user.list.component.html',
  providers: [UserService]
})
export class UserListComponent implements OnInit{
    public users: Array;

    constructor(private userService: UserService){
        this.users = [];
    }

    ngOnInit(): void {
        this.userService.list().subscribe((response)=>{
            this.users = response;
        });
    }
}

If you take a look at the template you are going to see the bindings.
If you are familiar with angular1 you will see that some bindings are different.
Other interesting thing is the routerLink, in the browser if you click on this link you are going to go to ‘user/:id’ route with the id of the user.
list template

We hope this post is useful and you’re ready for our next post about systemjs.
If you want to download the code, please go to this github

Thanks for reading. See you soon!

Related posts

Comments are closed.