Tuesday, October 25, 2022
Angular tutorial part 5 : Learn Angular Routing and testing
Routing and
Routing
in Angular
• Component Router
• Navigating Routes
• Route Parameters
• Query Parameters
• Child Routes
Implement
routes first in app routing module
•
Basically this
helps creating menus to help user navigate to various components and pass
parameters to components.
•
There are various
ways routes can be implemented.
• One of the best ways => In application
Routing module import the route dependencies import { Routes, RouterModule ,ActivatedRoute } from '@angular/router';
• Routes take 2 params,the path name
and the target component,all the app routes can be defined here
• const routes: Routes = [{path: 'Main', component:AppComponent}, {path: 'Form', component: FormappComponent},];
• Pass this routes to
the NGModule imports
• @NgModule({
• imports: [RouterModule.forRoot(routes)],
• exports: [RouterModule]
• })
• To create a default
routing module when component is created ,use the cli command
• ng g m [ModuleName]
--routing
Create
a new Menu component
•
Generate a new
component within the app called menu
•
Add the menu links
• Welcome To Menu
• <nav> <a class="button" routerLink="Main">Main</a> |
• <a class="button" [routerLink]="['Form',{value1: 'bar'}]">USerForm1</a> </nav>
• <router-outlet></router-outlet>
•
Router link param
takes two params to genereate hyperlink 1. routename defined in route,then
param if needed to be sent to second component.
•
Redirect the
application now to point to this menu component as entry point,to do that
•
Change the
bootstrap in the appmodule to menucomponent
• bootstrap: [MenuComponent ]
• Now when the application starts you will see the 2
menu links ->main and form,each pointing to the component we have created
earlier and defined in the routes
•
Passing
and Reading params
•
Routerlink can take
route and params as inputs,the following router link redirects to form
component and sends a param value1 .
•
<a class="button" [routerLink]="['Form',{value1: 'bar'}]">USerForm1</a> </nav>
•
To Read the param
in the target component,we will use activatedroute module
• import { Router,ActivatedRoute } from '@angular/router';
and inject
•
In component
constructor only constructor(private _Activatedroute:ActivatedRoute,) { }
•
And in the components of form,we will read the
params,using activatedroute,parammap and an observable.
•
this._Activatedroute.paramMap.subscribe(params => {
•
console.log(params);
•
console.log(params.get('value1'));//params passed to this component by routing
•
Component Router
• • Use the
router-outlet directive to tell Angular where you
• want a route to put
its template <router-outlet></
• router-outlet>
Adding
the routeconfig to component or module
• @RouteConfig([
• {path: '/home', name: 'Home', component:
HomeComponent, useAsDefault: true},
• {path: '/about', name: 'About', component:
AboutComponent},
• {path: '/experiments', name: 'Experiments',
component: ExperimentsComponent}
• ])
• export class
AppComponent {}
• <div
id="container">
• <router-outlet></router-outlet>
• </div>
Navigating
Routes
• Add a routerLink
attribute directive to an anchor tag
• Bind it to a template expression that
returns an array of route link parameters Users
•
Navigate imperatively by importing Router, injecting it, and then calling
.navigate() from within a component method
• We pass the same array of parameters as
we would to the routerLink directive this._router.navigate( ['Users'] );
• <div
id="menu">
• <a [routerLink]="['/Home']"
class="btn">Home</a>
• <a [routerLink]="['/About']"
class="btn">About</a>
• <a
[routerLink]="['/Experiments']"
class="btn">Experiments</a>
• </div>
Routerlink
• Add a routerLink
attribute directive to an anchor tag
• Bind it to a template expression that
returns an array of route link parameters Users
•
Navigate imperatively by importing Router, injecting it, and then calling
.navigate() from within a component method
• We pass the same array of parameters as
we would to the routerLink directive this._router.navigate( ['Users'] );
• Programmatically allows you to navigate to
path
export class App {
constructor(private _router: Router) {}
navigate(route) {
this._router.navigate([`/${route}`]); }
}
Query Parameters
• Denotes an optional value for a
particular route
• Do not add query parameters to the route
definition
• { path:'/users',
name: UserDetail, component:
• UserDetail }
• Add as a parameter to the routerLink
template
• expression just
like router params: <a
• [routerLink]="['Users',
{id: 7}]"> {{user.name}} </a>
• Also accessed by injecting RouteParams
into a component
Query
Params
•
<div>
•
<button
[routerLink]="['./MyComponent', {id: 1}]">
•
My Component Link</button>
•
<button
[routerLink]="['./AnotherComponent', {queryParam: 'bar'}]">
•
Another Component Link</button>
•
</div>
•
Com
Query
Params
• import { Component
} from 'angular2/core';
• import {
RouteParams } from 'angular2/router';
• @Component({
• selector: 'my-component',
• template: `<h1>my component
({{routeParams.get('id')}})!</h1>`
• })
• export class
MyComponent {
• constructor(routeParams: RouteParams) {
• this.routeParams = routeParams;
• }
• }
Child
Routes
• Ideal for creating reusable components
• Components with child routes are
“ignorant” of the parents’ route implementation
• In the parent route config, end the path
with /…
• In the child config, set the path
relative to the parent path
• If more than one child route, make sure
to set the default route
Child
Routes
• @RouteConfig([ {
• path:'/another-component/...',
• name: 'AnotherComponent',
• component: AnotherComponent }
• ])
• export class App
{}@RouteConfig([
• {
• path:'/first', name: 'FirstChild',
• component: FirstSubComponent }])
• export class
AnotherComponent {}
Testing
• Testing is good practise and mandatory in any project.
• Testing helps remove bugs and also check the
functionality of your application.
• Angular wraps
Jasmine methods
•
Import all necessary Jasmine methods from angular11/
•
testing
• Import the classes to test
•
Include providers by importing beforeEachProviders
• and then calling it
with a method that return
• TestBed is the
primary api for writing unit tests for Angular applications and libraries.
• Methods
• compileComponents()
• inject()
• get()
• execute()
• overrideModule()
• overrideComponent()
• overrideDirective()
• overridePipe()
• overrideProvider()
• overrideTemplateUsingTestingModule()
• createComponent()
Testing
a component
•
Create a component
with title =I love pizza
•
import
{ Component, OnInit } from '@angular/core';
•
@Component({
•
selector: 'app-pizza', templateUrl: './pizza.component.html',
styleUrls: ['./pizza.component.css']
•
})export
class PizzaComponent implements OnInit {
•
title = "I love pizza!" constructor() { } ngOnInit() {
}}
•
We will create a
test to see that component is create with title “I love pizza”
Testing
a component (contd..)
• Writing tests in
Angular is easy, now we are going to write a simple test within the describe() function.
• it(`should have a
title 'I love pizza!'`, async(() => { //test has to be written within it
• fixture =
TestBed.createComponent(PizzaComponent);
//create an instance of the component using testbesd class
• component =
fixture.debugElement.componentInstance; //once the component is rendered
• expect(component.title).toEqual('I love
pizza!');//check for whether the component title is equal to “I love pizza”
• //expect asserts or compares values to expected values
• }));
•
Run ng test
• To specifically test one test spect only ->ng test --main
./src/app/app.component.spec.ts
Testing
services
• To test a service,
you set the providers metadata property with an array of the services that
you'll test or mock.
• let service:
MyserviceService;
• beforeEach(() =>
{ TestBed.configureTestingModule({
providers: [MyserviceService
• ] });});
• Then inject it
inside a test by calling TestBed.inject() with the service class as the
argument.
• it('should use
ValueService', () => { service = TestBed.inject(MyserviceService
• );
expect(service.showTodayDate()).toBe('real value'); });
Angular tutorial part 4 - Learn Angular The HTTP Module •Methods • Observable.toPromise • Error Handling • Header Pipes
Server communication
• The HTTP Module
•Methods
•
Observable.toPromise
• Error Handling
• Header
Pipes
Http
Module
• Http module basically is used to connect to resource
on the network
• and process the result.
• Returns an
observable
Http
module
• request: performs any type
of http request
• get: performs a
request with GET http method
• post: performs a
request with POST http method
• put: performs a
request with PUT http method
• delete: performs a
request with DELETE http method
• patch: performs a
request with PATCH http method
• head: performs a
request with HEAD http method
To use
http in component
•
Import httpmodule
in app module
• import { HttpClientModule } from '@angular/common/http';
• Add to imports ,
imports: [ HttpClientModule ],
in app module
•
Import the
following in component ts
• import { HttpClient, HttpHeaders,HttpHeaderResponse } from "@angular/common/http";
• Inject httpclient in constructor: constructor(private http: HttpClient) { }
Making
http post call
• Real time code
creates user record in mysql via springboot endpoint,angular basically calls
this springboot endpoint and passes and user class object.
•
• private url = 'http://127.0.0.1:8080/insertuser';
• CreateUser(user: User): Observable<any>{
• var httpOptions = {
• headers: new HttpHeaders({ 'Content-Type': 'application/json'})
• };
• console.log('value from service'+JSON.stringify(user));
• return this.http.post<User>(this.url,user,httpOptions);
•
Walk
through sample code
• loadItems() {
• return this.http.get(BASE_URL)
//basically a get call is made using the http module
• .map(res =>
res.json())/returns a json respononse
• .toPromise();
• }
• createItem(item:
Item) {
• return this.http.post(`${BASE_URL}`,
JSON.stringify(item), HEADER)
• //basically a post call is made on the http module
• .map(res =>
res.json()) //process the json response
• .toPromise();
• }
Http
Put and Delete
• updateItem(item:
Item) {
• return this.http.put(`${BASE_URL}${item.id}`,
• JSON.stringify(item),
HEADER)
• .map(res =>
res.json())
• .toPromise();
• }
• deleteItem(item:
Item) {
• return this.http.delete(`${BASE_URL}${item.id}`)
• .map(res =>
res.json())
• .toPromise();
• }
Using
Observable
• Observables
are really just functions that throw values
• . Objects called
observers define callback functions for next(), error(), and complete().•
Composed of subjects and observers
• A subject performs some logic and
notifies the
• observer at the appropriate
times
•
Observable.subscribe is used to check result of the
method
• We finalize an
observable stream by subscribing to it
• The subscribe
method accepts three event handlers
• onNext is called when new
data arrives
• onError is called when an
error is thrown
• onComplete is called when the
stream is completed
• source.subscribe(
• x =>
console.log('Next: ' + x),
• err =>
console.log('Error: ' + err),
• () =>
console.log('Completed'));
• Observable.
Error
handling
• We should always
handle errors
• Chain the .catch
method on an observable
• Pass in a callback
with a single error argument
•
this.http.get('users.json')
•
.catch(error => {
•
console.error(error);
•
return Observable.throw(error.json().error || 'Server
error');
• });
Using
Promise
• Promise is another way we can hit a network url and
assess the results. Promise is asynch ,that it waits for the response.
•
We
can chain any HTTP with toPromise
• Then we can use .then
and .catch to resolve the promise
• Headers can be
added,post of get can be done.
•
this.http.get('users.json')
•
.toPromise()
•
.then(res => res.json().data) //handle the data
•
.then(users => this.users = users)
• .catch(this.handleError);/if
error
Adding
Headers
• Import Headers and
RequestOptions:
• import {Headers,
RequestOptions} from 'angular2/http';
• Headers are an
instance of the Headers class
• Pass in an object
with each header as a key-value pair
• Used mainly to pass security token params
•
Then
pass this Headers instance into a new RequestOptions
• instance
•
let headers = new Headers({ 'Content-Type':
'application/json' });
•
let options = new RequestOptions({ headers: headers });
• this.http.post('users.json',
'{}', options);
Pipes
• •What are Pipes?
• • Built-in Pipes
• • Custom Pipes
• • Async Pipes
What
are pipes
• A pipe takes in
data as input and transforms it to a desired
• output
• We use them in our
templates with interpolation:
•
<p>User created on {{ created_at | date }}</p>
• Include parameters
to a pipe by separating them with a colon:
•
<p>User created on {{ created_at |
date:"MM/dd/yy" }}</p>
• Pipes are
chain-able:
• <p>User
created on {{ created_at | date | uppercase }}</p>
Build
in Pipes
• DatePipe
•
<p>User created on {{ user.created_at | date
}}</p>
• UpperCasePipe
•
<p>Middle Initial: {{ user.middle | uppercase
}}</p>
• LowerCasePipe
•
<p>Username: {{ user.username | lowercase
}}</p>
• CurrencyPipe
•
<p>Price Plan: {{ user.plan.price | currency }}</p>
• PercentPipe
• <p>Data
Usage: {{ user.usage | percent }}</p>
Build
your own custom pipes
•
import { Pipe, PipeTransform } from 'angular2/core';
• Create a class that
implements the PipeTransform interface
• and includes a transform
method:
•
export class ReversePipe implements PipeTransform {
•
transform(value:string, args:string[]) : any {
•
return value.reverse();
•
}
• }
Pipes
for Http calls
• Resolves async data
(observables/promises) directly in the template
• Skips the process
of having to manually subscribe to async methods
• in the component
and then setting those values for the template to
• bind to
• Component
attribute:
•
asyncAttribute<string> = new Promise((resolve,
reject) => {
•
setTimeout(() => resolve('Promise resolved'), 500);
•
})
• Template: <p>Async
result: {{asyncAttribute | async}}</p>
Subscribe to:
Posts (Atom)