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
Details configuration
Faster and customizable
Less buggy
Understand workflow better
For curios/expert users
Let’s start
Requirements
Linux, MacOS or Windows
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
Our application is divided in two parts. -Application itself & Application bootstrap
Our modules, routes, components & services live here.
We bootstrap our app depending on what platform were developing for, and add any required polyfills & vendors.
Typescript config, npm packages, scripts, webpack config, express server, and so on...
Angular App Hierarchy
@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:
*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?