Angular Building blocks

 @kokkisajee

www.sajeetharan.com

In a nutshell

Communities

Social Developer

Recognitions

Cloud Solution Architect @Microsoft

First GDE,MCT and MVP from SL

Top stackoverflow contributor

 

I'm Sajeetharan Sinnathurai

@sajeetharan
@kokkisajee
@sajeetharan
@sajeetharan

A small story !

 @kokkisajee

What the heck is Angular?

From Framework to Platform

 11,038

 @kokkisajee

 

 

 

 

 

ONE TEAM + CORE COMPETENCE + ONE CODE BASE

=

LOTS OF STUFF

 

Why Angular?

HEROES DON'T ALWAYS WEAR CAPES

SOMETIMES THEY CODE ANGULAR

Typescript

=

Javascript + Types

Typed JavaScript with #TypeScript

Classes

Types

Interfaces

Private methods

class Person {
    private name: string;
    private age: number;
    private salary: number;

    constructor(name: string, age: number, salary: number) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
    
    toString(): string {
        return `${this.name} (${this.age}) (${this.salary})`;
    }
}

Angular CLI

Webpack

. Wraps Webpack

. Simple to configure

. Handy commands for     generating classes,   components …

. Cannot do advance     configurations

. A bit slow

.Details configuration

.Faster and customizable

.Less buggy

.Understand workflow better

.For curios/expert users

.A lot of stuff to manage

Angular App Structure

Application Source

Our application is divided in two parts. -Application itself & Application bootstrap

Angular App

Our modules, routes, components & services live here.

Angular Boostrap

We bootstrap our app depending on what platform were developing for, and add any required polyfills & vendors.

Configuration

Typescript config, npm packages, scripts, webpack config, express server, and so on...

How this magic happens?

Data Binding

[( NGMODEL )]

    <input [(ngModel)]="name" />

Angular App Hierarchy

Main App
Main Module
Components
Services, Pipes, Classes
Child Module.

Building Blocks of Angular

  • Module
  • Component
  • Pipes
  • Directives
  • Metadata
  • Services
  • Dependency Injection

"MS Dhoni is a Microsoft Certified Professional Developer"

@NgModule

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {HttpModule} from '@angular/http';

import {AppComponent} from './app.component';
import { HomeComponent } from './home/home.component';
import {AppRoutingModule} from "./app-routing.module";

@NgModule({
    declarations: [
        AppComponent,
        HomeComponent
    ],
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        AppRoutingModule
    ],
    providers: [/**DataService, UserService**/],
    bootstrap: [AppComponent]
})
export class AppModule {
}

Help organize an application into cohesive blocks of functionality.

This is Angular

The rest is a standard JS/Typescript class

@Component

import {Component, OnInit} from '@angular/core';
import {Router} from "@angular/router";
import {UserService} from "../shared/services/user.service";

@Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.scss']
})

export class LoginComponent implements OnInit {

    constructor(private us:UserService, private route: Router) {
    }

    ngOnInit() {
    }

    login() {
        this.us.login();
    }

    logout() {
        this.us.logout();
    }
}

Components are the most basic building block of an UI in an Angular application

Decorator

Annotate this is a Angular component

Angular Injects for us every dependency

@Directives

Components still have directives

<div [ngStyle]="setStyles()">
  <p *ngFor="let player of players">...</p>
</div>
  • No more ng-show, ng-hide, ng-click but functionality is still available
  • Types of Angular Directives :

Attribute Directives : ngStyle, ngClass, …Structural Directives : ngIf, ngSwitch, ngFor, …

Pipes

Components can display formatted data

import { Pipe } from '@angular/core';
import { PipeTransform } from '@angular/core';
@Pipe({name: 'filterReviewByStatus'})
export class FilterReviewByStatusPipe implements PipeTransform {


}

DatePipe, UpperCasePipe, LowerCasePipe, CurrencyPipe, PercentPipe ...

<p>
    The chained mario's birthday is 
    {{  birthday | date:'fullDate' | uppercase}}
</p>

Services

Components inject services

Service is a class that encapsulates some sort of functionality and provides it as a service for the rest of the application

export class UserService {
  private users: User[] = [];

  constructor(
    private backend: BackendService,
    private logger: Logger
  ) { ... }

  getAllUSers() {
    return this.users;
  }
}

Let's Build

npm install -g @angular/cli

Install:

Generate a our first app:

ng new beerApp --routing --style=scss
cd beerApp
npm start

Create a component

ng g c home
ng generate component home

Using Angular CLI

Short version of the above

What we get:

  • Template HTML, the component view
  • SCSS/CSS a style file
  • SPEC.TS unit test for the component
  • TS the main Typescript file*

*Only this file is mandatory for creating a component

  • Template HTML, the component view
  • SCSS/CSS a style file
  • SPEC.TS unit test for the component
  • TS the main Typescript file*

Use a component

A component can be used inside another component using its meta data selector

import {Component, OnInit} from '@angular/core';
import {Http, Headers} from "@angular/http";

@Component({
    selector: 'app-home',
    templateUrl: './home.component.html',
    styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {

    constructor(private http: Http) {
    }

    ngOnInit() {

    }
}

home.component.ts

app.component.html

<h1>
 App Works!!
</h1>

<app-home></app-home>

Let's add some style

Open index.html and add the following css link in the head section:

<link rel="stylesheet" 
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.1/css/materialize.min.css">

Set Routing

Tell Angular which component to load when navigating

Open app-routing.module.ts

import {NgModule} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';
import {HomeComponent} from "./home/home.component";

const routes: Routes = [
    {path: 'home', component: HomeComponent},
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule {
}

Tell to load HomeComponent when navigating in the browser domain.com/home

We keep adding routes for each components we want to navigate

Add a navigation bar

Create a set of links to navigate the app sections. Replace the content of app.component.html with:

<nav>
    <div class="nav-wrapper">
        <a href="#" class="brand-logo">Logo</a>
        <ul id="nav-mobile" class="right hide-on-med-and-down">
            <li><a [routerLink]="['/home']">Home</a></li>
            <li><a href="">Search Beers</a></li>
            <li><a href="">Login</a></li>
        </ul>
    </div>
</nav>

<div class="container">
    <router-outlet></router-outlet>
</div>

Tell to Angular where to display the content when navigating between components

This is a Directive to link to specific parts of your app.

Home Component

Request to the server

home.component.ts

import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Beer } from '../models/beer';

@Component({
    selector: 'app-home',
    templateUrl: './home.component.html',
    styleUrls: ['./home.component.scss']
})

export class HomeComponent implements OnInit {

    beer: Beer;

    constructor(private http: HttpClient) {
    }

    ngOnInit() {
        const _options = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) };
        this.http.get('/api/v2/beer/random?key=a81493ef1e81335e3dc2fc1d5e394053&hasLabels=Y', _options).subscribe(
            (response: any) => {
                const json = response;
                this.beer = new Beer();
                this.beer.name = json.data.nameDisplay;
                this.beer.description = json.data.style.description;
                this.beer.image = json.data.labels.medium;

            }
        );
    }
}

Home Component

Display a random beer and set a button to change beer

home.component.html

<div class="col s12 m7">
    <h4 class="header">A Random Beer</h4>
    <div class="card horizontal">
        <div class="card-image">
            <img [src]="data.image">
        </div>
        <div class="card-stacked">
            <div class="card-content">
                <p>{{ data.description }}</p>
            </div>
            <div class="card-action">
                <a href="#">{{ data.name }}</a>
            </div>
        </div>
    </div>
</div>

String interpolation

Property binding

CORS fix

proxy.json

{
    "/api": {
        "target": "http://api.brewerydb.com",
        "secure": false,
        "changeOrigin": true,
        "logLevel": "debug",
        "pathRewrite": {
            "^/api": "/"
        }
    }
}

Launch the cli with the following

ng serve --proxy-config=proxy.conf.json

Hope things go smoothly..

We should see

Otherwise...

Lfe cycle hooks

•Implemented by components and directives

• Methods which are called when specific events occur

• ngOnChanges() – called when data-bound input properties are set/reset

• ngOnInit() – called shortly after the component is created

• ngOnDestroy() – Called just before Angular destroys the directive component

Search Beer Component

ng g c search-beer

End Point

/api/v2/search?key=a81493ef1e81335e3dc2fc1d5e394053&type=beer

Search for beers using a input field and list them

Search Beer Component

search-beer.component.ts

import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { FormControl } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { switchMap } from 'rxjs/operators';
import { Beer } from '../models/beer';
@Component({
    selector: 'app-search-beer',
    templateUrl: './search-beer.component.html',
    styleUrls: ['./search-beer.component.scss']
})
export class SearchBeerComponent implements OnInit {

    termInput = new FormControl();
    beers: Beer[] = [];
    constructor(private http: HttpClient) {
    }

    ngOnInit() {
        this.termInput.valueChanges.pipe(term => {
            return this.search(term);
        }).subscribe((res: any) => {
            this.beers = res.data;
        });
    }

    search(term) {
        return this.http.get(`/api/v2/search?key=a81493ef1e81335e3dc2fc1d5e394053&type=beer&q=${term}`);
    }

    onKey(value) {
        console.log(value);
    }
}

Search Beer Component

Next steps:

- Display a list of beers

- Search with the API

- Create a reusable component

Q/A

Want some stickers?

Where to go from here?

- Do the exercise in the given pdf

- Look at  Demo Application if you were stuck anytime during the      session

- Tweet @kookisajee

- We will meet again with the session "High level Angular application architecture"

- Join Stackoverflowers-SriLanka and volunteer Ng-SriLanka

 

Key Building Blocks of a Typical Angular Application

By Sajeetharan Sinnathurai

Key Building Blocks of a Typical Angular Application

  • 12,372