Dive into Angular

 

Session I

 

 

Sajeetharan Sinnathurai

Saiyaff Farouk

Senior Tech Lead | MVP

Software Engineer |Angular Enthusiast 

Web Development has changed

Angular

To save your day

Typescript

=

Javascript + Types

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

Let’s start

Requirements

  • Linux, MacOS or Windows

  • Node 6.9.0 or higher, with NPM 3 or higher.
  • Editor:  Visual Studio Code

Angular CLI

npm install -g @angular/cli

Install:

Generate a our first app:

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

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...

Angular App Hierarchy

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

@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

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

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...

Data Binding

<Add code here for data binding examples of all the types..>

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

Pipes

Pipes transform displayed values within a template.

import { Component } from '@angular/core';

@Component({
  selector: 'hero-birthday',
  template: `<p>The hero's birthday is {{ birthday | date }}</p>`
})

export class HeroBirthdayComponent {
  birthday = new Date(1988, 3, 15); // April 15, 1988
}

Service

An Angular service is a class that encapsulates some sort of functionality and provides it as a service for the rest of your application.

Angular uses DI to provide services

Create a service with cli:

ng g service request

Decorator tells TypeScript to emit metadata about the service. The metadata specifies that Angular may need to inject other dependencies into this service.

import {Injectable} from '@angular/core';

@Injectable()//optional: needed only if this service has dependencies
export class RequestService {
    constructor() {
    }
}

Q/A

Want some stickers?

Where to go from here?

Angular Session - UCSC

By Sajeetharan Sinnathurai

Angular Session - UCSC

  • 1,256