Angular 8
Angular 8
4 Components :
app-routing.module.ts - This file contains routing configuration. The purpose of this file is to load and
configure the router in a separate file for readability. The module class name of this file is
AppRoutingModule by convention and it is imported by the root AppModule in app.module.ts file.
app.component.css - This is the component view's stylesheet file. Every component has one or more
associated style-sheet files. This file can also be in other formats: CSS, Sass, Stylus, or Less.
app.component.html - This is the component view's HTML template file.
app.component.spec.ts - This is the component's test file which is also known as a spec file. The file
extension .spec.ts helps tools to recognize it as a file containing the tests.
app.component.ts - This file contains all of the component's code for controlling its functionality.
app.module.ts - Every Angular application contains at least one NgModule class, the root module, which
is commonly referred to as AppModule and is in the src/app/app.module.ts file. This root NgModule is to
define Angular modules as well as to startup your application.
1
How to Create a new Component in Angular?
Use the following command to create a new component in your Angular project:
1. Lets start by creating a new Angular project using the Angular CLI ng new project-name command as
shown in the example below:
ng new my-sample-app
2. When you are prompted with Would you like to add Angular routing? Choose Yes by pressing Y.
3. When you see Which stylesheet format would you like to use? Choose CSS and press Enter.
4. After the project gets created, navigate to the project folder:
cd my-sample-app
8. The above command will create the following component files in src/app/navbar/ directory and will also
register NavbarComponent to the src/app/app.module.ts file:
o navbar.component.css
o navbar.component.html
o navbar.component.spec.ts
o navbar.component.ts
If you go to src/app/app.module.ts file of your Angular project, you will see entry
of NavbarComponent as shown in the example below:
src/app/app.module.ts
import { NgModule } from '@angular/core';
2
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
//Enry of NavbarComponent
import { NavbarComponent } from './navbar/navbar.component';
@NgModule({
declarations: [
AppComponent,
//Enry of NavbarComponent
NavbarComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
9. Now, go to src/app/navbar/navbar.components.ts file and find the value of selector. Here, the value
of selector is app-navbar as shown in the example below:src/app/navbar/navbar.components.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
10. Go to the root src/app/app.component.html file and remove everything except this line <router-
outlet></router-outlet>. Copy the value of selector from the newly
created src/app/navbar/navbar.components.ts file to src/app/app.component.html. Your
root src/app/app.component.html file should look like this:
3
<app-navbar></app-navbar>
<router-outlet></router-outlet>
11. Now, go to navbar component HTML view file at src/app/navbar/navbar.component.html and add the
HTML code to display navbar to it as shown in the example below:
<div class="navbar">
<a class="active" href="#">Home</a>
<a href="#">About</a>
<a href="#">Services</a>
<a href="#">Contact</a>
</div>
12. Next, add the following CSS to the style-sheet file of navbar component
at src/app/navbar/navbar.component.css:
.navbar {
background-color: rgb(82, 81, 81);
overflow: hidden;
}
.navbar a {
color: #f2f2f2;
text-align: center;
float: left;
text-decoration: none;
font-size: 16px;
padding: 14px 16px;
}
.navbar a:hover {
background-color: #f2f2f2;
color: rgb(46, 45, 45);
}
.navbar a.active {
background-color: #0446aa;
color: white;
}
13. Go to your browser and check your application page at http://localhost:4200/. The resulting page should
be something like this:
4
Congratulations! you have learned how to create and use a component in an Angular application.
4.4.2 Components
Components are building block of Angular application. The main job of Angular Component is to
generate a section of web page called view. Every component will have an associated template and it
will be used to generate views.
Let us learn the basic concept of component and template in this chapter.
Add a component
5
Component class, Template and stylesheet are created.
AppModule is updated with new component.
Add title property to ExpenseEntryComponent (src/app/expense-entry/expense-entry.component.ts)
component.
import { Component, OnInit } from '@angular/core'; @Component({
selector: 'app-expense-entry',
templateUrl: './expense-entry.component.html', styleUrls: ['./expense-entry.component.css']
})
export class ExpenseEntryComponent implements OnInit {
title: string;
constructor() { }
ngOnInit() {
this.title = "Expense Entry"
}
}
Update template, src/app/expense-entry/expense-entry.component.htmlwith below content.
<p>{{ title }}</p>
Open src/app/app.component.html and include newly created component.
<h1>{{ title }}</h1>
<app-expense-entry></app-expense-entry>
Here,
app-expense-entry is the selector value and it can be used as regular HTML Tag.
Finally, the output of the application is as shown below −
We will update the content of the component during the course of learning more about templates.
Templates
The integral part of Angular component is Template. It is used to generate the HTML
content. Templates are plain HTML with additional functionality.
6
Attach a template
Template can be attached to Angular component using @component decorator’s meta data. Angular
provides two meta data to attach template to components.
templateUrl
We already know how to use templateUrl. It expects the relative path of the template file. For example,
AppComponent set its template as app.component.html.
templateUrl: './app.component.html',
template
template enables to place the HTML string inside the component itself. If the template content is
minimal, then it will be easy to have it Component class itself for easy tracking and maintenance
purpose.
@Component({
selector: 'app-root',
templateUrl: `<h1>{{ title }}</h1>`,
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'Expense Manager';
constructor(private debugService : DebugService) {} ngOnInit() {
this.debugService.info("Angular Application starts");
}
}
Attach Stylesheet
Angular Templates can use CSS styles similar to HTML. Template gets its style information from two
sources, a) from its component b) from application configuration.
Component configuration
Component decorator provides two option, styles and styleUrls to provide CSS style information to its
template.
Styles − styles option is used to place the CSS inside the component itself.
styles: ['h1 { color: '#ff0000'; }']
styleUrls − styleUrls is used to refer external CSS stylesheet. We can use multiple stylesheet as
well.
styleUrls: ['./app.component.css', './custom_style.css']
Application configuration
Angular provides an option in project configuration (angular.json) to specify the CSS stylesheets. The
styles specified in angular.json will be applicable for all templates. Let us check our angular.json as
shown below −
{
"projects": {
"expense-manager": {
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser", "options": {
"outputPath": "dist/expense-manager",
7
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
},
}
}},
"defaultProject": "expense-manager"
}
Here,
styles option setssrc/styles.css as global CSS stylesheet. We can include any number of CSS stylesheets
as it supports multiple values.
Include bootstrap
Let us include bootstrap into our ExpenseManager application using styles option and change the
default template to use bootstrap components.
Open command prompt and go to ExpenseManager application.
cd /go/to/expense-manager
Install bootstrap and JQuery library using below commands
npm install --save bootstrap@4.5.0 jquery@3.5.1
Here,
We have installed JQuery, because, bootstrap uses jquery extensively for advanced components.
Option angular.json and set bootstrap and jquery library path.
{
"projects": {
"expense-manager": {
"architect": {
"build": {
"builder":"@angular-devkit/build-angular:browser", "options": {
"outputPath": "dist/expense-manager",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": [
"src/favicon.ico",
8
"src/assets"
],
"styles": [
"./node_modules/bootstrap/dist/css/bootstrap.css", "src/styles.css"
],
"scripts": [
"./node_modules/jquery/dist/jquery.js", "./node_modules/bootstrap/dist/js/bootstrap.js"
]
},
},
}
}},
"defaultProject": "expense-manager"
}
Here,
scripts option is used to include JavaScript library. JavaScript registered through scripts will be
available to all Angular components in the application.
Open app.component.html and change the content as specified below
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark static-top">
<div class="container">
<a class="navbar-brand" href="#">{{ title }}</a> <button class="navbar-toggler" type="button"
data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-
expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon">
</span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home
<span class="sr-only">(current)
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Report</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Add Expense</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
</div>
</div>
</nav>
<app-expense-entry></app-expense-entry>
Here,
9
Used bootstrap navigation and containers.
Open src/app/expense-entry/expense-entry.component.html and place below content.
<!-- Page Content -->
<div class="container">
<div class="row">
<div class="col-lg-12 text-center" style="padding-top: 20px;">
<div class="container" style="padding-left: 0px; padding-right: 0px;">
<div class="row">
<div class="col-sm" style="text-align: left;"> {{ title }}
</div>
<div class="col-sm" style="text-align: right;">
<button type="button" class="btn btn-primary">Edit</button>
</div>
</div>
</div>
<div class="container box" style="margin-top: 10px;">
<div class="row">
<div class="col-2" style="text-align: right;">
<strong><em>Item:</em></strong>
</div>
<div class="col" style="text-align: left;">
Pizza
</div>
</div>
<div class="row">
<div class="col-2" style="text-align: right;">
<strong><em>Amount:</em></strong>
</div>
<div class="col" style="text-align: left;">
20
</div>
</div>
<div class="row">
<div class="col-2" style="text-align: right;">
<strong><em>Category:</em></strong>
</div>
<div class="col" style="text-align: left;">
Food
</div>
</div>
<div class="row">
<div class="col-2" style="text-align: right;">
<strong><em>Location:</em></strong>
</div>
<div class="col" style="text-align: left;">
Zomato
</div>
</div>
<div class="row">
<div class="col-2" style="text-align: right;">
<strong><em>Spend On:</em></strong>
</div>
10
<div class="col" style="text-align: left;">
June 20, 2020
</div>
</div>
</div>
</div>
</div>
</div>
Restart the application.
The output of the application is as follows −
Angular 8 Directives
The Angular 8 directives are used to manipulate the DOM. By using Angular directives, you can change
the appearance, behavior or a layout of a DOM element. It also helps you to extend HTML.
11
Angular 8 directives can be classified in 3 categories based on how they behave:
o Component Directives
o Structural Directives
o Attribute Directives
Component Directives: Component directives are used in main class. They contain the detail of how the
component should be processed, instantiated and used at runtime.
Structural Directives: Structural directives start with a * sign. These directives are used to manipulate
and change the structure of the DOM elements. For example, *ngIf directive, *ngSwitch directive, and
*ngFor directive.
Attribute Directives: Attribute directives are used to change the look and behavior of the DOM
elements. For example: ngClass directive, and ngStyle directive etc.
o ngClass Directive: The ngClass directive is used to add or remove CSS classes to an HTML
element.
o ngStyle Directive: The ngStyle directive facilitates you to modify the style of an HTML element
using the expression. You can also use ngStyle directive to dynamically change the style of your
HTML element.
12
Angular 8 ngIf Directive
The ngIf Directives is used to add or remove HTML Elements according to the expression. The
expression must return a Boolean value. If the expression is false then the element is removed, otherwise
element is inserted. It is similar to the ng-if directive of AngularJS.
ngIf Syntax
1. <p *ngIf="condition">
2. condition is true and ngIf is true.
3. </p>
4. <p *ngIf="!condition">
5. condition is false and ngIf is false.
6. </p>
The ngIf directive does not hide the DOM element. It removes the entire element along with its subtree
from the DOM. It also removes the corresponding state freeing up the resources attached to the element.
The *ngIf directive is most commonly used to conditionally show an inline template. See the following
example:
1. @Component({
2. selector: 'ng-if-simple',
3. template: `
4. <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button>
5. show = {{show}}
6. <br>
7. <div *ngIf="show">Text to show</div>
8. `
9. })
10. export class NgIfSimple {
11. show: boolean = true;
12. }
13
1. @Component({
2. selector: 'ng-if-else',
3. template: `
4. <button (click)="show = !show">{{show ? 'hide' : 'show'}}</button>
5. show = {{show}}
6. <br>
7. <div *ngIf="show; else elseBlock">Text to show</div>
8. <ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>
9. `
10. })
11. export class NgIfElse {
12. show: boolean = true;
13. }
Angular 8 *ngFor Directive
The *ngFor directive is used to repeat a portion of HTML template once per each item from an iterable
list (Collection). The ngFor is an Angular structural directive and is similar to ngRepeat in AngularJS.
Some local variables like Index, First, Last, odd and even are exported by *ngFor directive.
Syntax of ngFor
To Use ngFor directive, you have to create a block of HTML elements, which can display a single item of
the items collection. After that you can use the ngFor directive to tell angular to repeat that block of
HTML elements for each item in the list.
First, you have to create an angular Application. After that open the app.component.ts and add the
following code.
The following Code contains a list of Top 3 movies in a movies array. Let's build a template to display
these movies in a tabular form.
Now, open the app. component.html and add the following code:
15
17. <tr *ngFor="let movie of movies;">
18. <td>{{movie.title}}</td>
19. <td>{{movie.director}}</td>
20. <td>{{movie.cast}}</td>
21. <td>{{movie.releaseDate}}</td>
22. </tr>
23. </tbody>
24. </table>
25. </div>
26. </div>
27. </div>
When you run the application, It will show the movies in tabular form.
In Angular 8, ngSwitch is a structural directive which is used to Add/Remove DOM Element. It is similar
to switch statement of C#. The ngSwitch directive is applied to the container element with a switch
expression.
Syntax of ngSwitch
1. <container_element [ngSwitch]="switch_expression">
2. <inner_element *ngSwitchCase="match_expresson_1">...</inner_element>
3. <inner_element *ngSwitchCase="match_expresson_2">...</inner_element>
4. <inner_element *ngSwitchCase="match_expresson_3">...</inner_element>
5. <inner_element *ngSwitchDefault>...</element>
6. </container_element>
ngSwitchCase
In Angular ngSwitchCase directive, the inner elements are placed inside the container element. The
ngSwitchCase directive is applied to the inner elements with a match expression. Whenever the value of
the match expression matches the value of the switch expression, the corresponding inner element is
added to the DOM. All other inner elements are removed from the DOM
If there is more than one match, then all the matching elements are added to the DOM.
ngSwitchDefault
You can also apply the ngSwitchDefault directive in Angular 8. The element with ngSwitchDefault is
displayed only if no match is found. The inner element with ngSwitchDefault can be placed anywhere
inside the container element and not necessarily at the bottom. If you add more than one ngSwitchDefault
directive, all of them are displayed.
Any elements placed inside the container element, but outside the ngSwitchCase or ngSwitchDefault
elements are displayed as it is.
16
ngSwitch Directive Example
1. class item {
2. name: string;
3. val: number;
4. }
5. export class AppComponent
6. {
7. items: item[] = [{name: 'One', val: 1}, {name: 'Two', val: 2}, {name: 'Three', val: 3}];
8. selectedValue: string= 'One';
9. }
1. <select [(ngModel)]="selectedValue">
2. <option *ngFor="let item of items;" [value]="item.name">{{item.name}}</option>
3. </select>
4. <div class='row' [ngSwitch]="selectedValue">
5. <div *ngSwitchCase="'One'">One is Pressed</div>
6. <div *ngSwitchCase="'Two'">Two is Selected</div>
7. <div *ngSwitchDefault>Default Option</div>
8. </div>
@Injectable({
providedIn: 'root',
17
})
export class HeroService {
constructor() { }
}
The @Injectable() decorator specifies that Angular can use this class in the DI system. The
metadata, providedIn: 'root', means that the HeroService is visible throughout the application.
Next, to get the hero mock data, add a getHeroes() method that returns the heroes from mock.heroes.ts.
src/app/heroes/hero.service.ts
content_copyimport { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes';
@Injectable({
// declares that this service should be created
// by the root application injector.
providedIn: 'root',
})
export class HeroService {
getHeroes() { return HEROES; }
}
For clarity and maintainability, it is recommended that you define components and services in separate
files.
If you do combine a component and service in the same file, it is important to define the service first, and
then the component. If you define the component before the service, Angular returns a run-time null
reference error.
Injecting services
Injecting services results in making them visible to a component.
To inject a dependency in a component's constructor(), supply a constructor argument with the
dependency type. The following example specifies the HeroService in
the HeroListComponent constructor. The type of heroService is HeroService.
src/app/heroes/hero-list.component (constructor signature)
content_copyconstructor(heroService: HeroService)
For more information, see Providing dependencies in modules and Hierarchical injectors.
Using services in other services
When a service depends on another service, follow the same pattern as injecting into a component. In the
following example HeroService depends on a Logger service to report its activities.
First, import the Logger service. Next, inject the Logger service in the HeroService constructor() by
specifying private logger: Logger within the parentheses.
When you create a class whose constructor() has parameters, specify the type and metadata about those
parameters so that Angular can inject the correct service.
Here, the constructor() specifies a type of Logger and stores the instance of Logger in a private field
called logger.
The following code tabs feature the Logger service and two versions of HeroService. The first version
of HeroService does not depend on the Logger service. The revised second version does depend
on Logger service.
src/app/heroes/hero.service (v2)
src/app/heroes/hero.service (v1)
src/app/logger.service
content_copyimport { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes';
import { Logger } from '../logger.service';
@Injectable({
providedIn: 'root',
})
18
export class HeroService {
getHeroes() {
this.logger.log('Getting heroes ...');
return HEROES;
}
}
In this example, the getHeroes() method uses the Logger service by logging a message when fetching
heroes.
Angular Service
We might come across a situation where we need some code to be used everywhere on the page. It can
be for data connection that needs to be shared across components, etc. Services help us achieve that.
With services, we can access methods and properties across other components in the entire project.
To create a service, we need to make use of the command line. The command for the same is
C:\projectA4\Angular 4-app>ng g service myservice
installing service
create src\app\myservice.service.spec.ts
create src\app\myservice.service.ts
WARNING Service is generated but not provided, it must be provided to be used
C:\projectA4\Angular 4-app>
The files are created in the app folder as follows
Following are the files created at the bottom - myservice.service.specs.ts and myservice.service.ts.
myservice.service.ts
import { Injectable } from '@angular/core';
@Injectable()
19
export class MyserviceService {
constructor() { }
}
Here, the Injectable module is imported from the @angular/core. It contains the @Injectable method
and a class called MyserviceService. We will create our service function in this class.
Before creating a new service, we need to include the service created in the main parent app.module.ts.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule} from '@angular/router';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
SqrtPipe,
AppComponent,
NewCmpComponent,
ChangeTextDirective
],
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: 'new-cmp',
component: NewCmpComponent
}
])
],
providers: [MyserviceService],
bootstrap: [AppComponent]
})
20
export class MyserviceService {
constructor() { }
showTodayDate() {
let ndate = new Date();
return ndate;
}
}
In the above service file, we have created a function showTodayDate. Now we will return the new Date
() created. Let us see how we can access this function in the component class.
app.component.ts
import { Component } from '@angular/core';
import { MyserviceService } from './myservice.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
@Component({
selector: 'app-new-cmp',
templateUrl: './new-cmp.component.html',
styleUrls: ['./new-cmp.component.css']
})
ngOnInit() {
this.todaydate = this.myservice.showTodayDate();
}
}
In the new component that we have created, we need to first import the service that we want and access the metho
<p>
{{newcomponent}}
</p>
<p>
Today's Date : {{todaydate}}
</p>
The selector of the new component is used in the app.component.html
If you change the property of the service in any component, the same is changed in other components
too. Let us now see how this works.
We will define one variable in the service and use it in the parent and the new component. We will again
change the property in the parent component and will see if the same is changed in the new component
or not.
In myservice.service.ts, we have created a property and used the same in other parent and new
component.
import { Injectable } from '@angular/core';
@Injectable()
export class MyserviceService {
serviceproperty = "Service Created";
constructor() { }
showTodayDate() {
let ndate = new Date();
return ndate;
}
}
22
Let us now use the serviceproperty variable in other components. In app.component.ts
, we are accessing the variable as follows
@Component({
selector: 'app-new-cmp',
templateUrl: './new-cmp.component.html',
styleUrls: ['./new-cmp.component.css']
})
23
Now when you execute it in the browser, the service property will be changed since the value of it is
changed in app.component.ts and the same will be displayed for the new-cmp.component.ts.
Also check the value in the console before it is changed.
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
If you see the highlighted code, we have imported the HttpModule from @angular/http and the same is
also added in the imports array.
Let us now use the http service in the app.component.ts.
import { Component } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
24
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
Let us understand the code highlighted above. We need to import http to make use of the service, which is done a
import 'rxjs/add/operator/map';
Once the map is done, the subscribe will log the output in the console as shown in the browser
25
If you see, the json objects are displayed in the console. The objects can be displayed in the browser too.
For the objects to be displayed in the browser, update the codes
in app.component.html and app.component.ts
import { Component } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private http: Http) { }
httpdata;
ngOnInit() {
this.http.get("http://jsonplaceholder.typicode.com/users").
map(
(response) ⇒ response.json()
).
subscribe(
(data) ⇒ {this.displaydata(data);}
)
}
displaydata(data) {this.httpdata = data;}
}
In app.component.ts, using the subscribe method we will call the display data method and pass the data
fetched as the parameter to it.
In the display data method, we will store the data in a variable httpdata. The data is displayed in the
browser using for over this httpdata variable, which is done in the app.component.html file.
<ul *ngFor = "let data of httpdata">
<li>Name : {{data.name}} Address: {{data.address.city}}</li>
</ul>
The json object is as follows
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
26
"lng": "81.1496"
}
},
Let us now add the search parameter, which will filter based on specific data. We need to fetch the data
based on the search param passed.
Following are the changes done in app.component.html and app.component.ts
app.component.ts
import { Component } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
27
searchparam = 2;
jsondata;
name;
constructor(private http: Http) { }
ngOnInit() {
this.http.get("http://jsonplaceholder.typicode.com/users?id="+this.searchparam).
map(
(response) ⇒ response.json()
).
subscribe((data) ⇒ this.converttoarray(data))
}
converttoarray(data) {
console.log(data);
this.name = data[0].name;
}
}
For the get api, we will add the search param id = this.searchparam. The searchparam is equal to 2. We
need the details of id=2 from the json file.
app.component.html
{{name}}
This is how the browser is displayed
We have consoled the data in the browser, which is received from the http. The same is displayed in the
browser console. The name from the json with id=2 is displayed in the browser.
28
Angular Routing
In a single-page app, you change what the user sees by showing or hiding portions of the display that
correspond to particular components, rather than going out to the server to get a new page. As users
perform application tasks, they need to move between the different views that you have defined.
To handle the navigation from one view to the next, you use the Angular Router. The Router enables
navigation by interpreting a browser URL as an instruction to change the view.
Common Routing Tasks
This topic describes how to implement many of the common tasks associated with adding the Angular
router to your application.
Generate an application with routing enabled
The following command uses the Angular CLI to generate a basic Angular application with an application
routing module, called AppRoutingModule, which is an NgModule where you can configure your routes.
The application name in the following example is routing-app.
content_copyng new routing-app --routing
When generating a new application, the CLI prompts you to select CSS or a CSS preprocessor. For this
example, accept the default of CSS.
Adding components for routing
To use the Angular router, an application needs to have at least two components so that it can navigate
from one to the other. To create a component using the CLI, enter the following at the command line
where first is the name of your component:
content_copyng generate component first
Repeat this step for a second component but give it a different name. Here, the new name is second.
content_copyng generate component second
The CLI automatically appends Component, so if you were to write first-component, your component
would be FirstComponentComponent.
<base href>
This guide works with a CLI-generated Angular application. If you are working manually, make sure
that you have <base href="/"> in the <head> of your index.html file. This assumes that
the app folder is the application root, and uses "/".
Importing your new components
To use your new components, import them into AppRoutingModule at the top of the file, as follows:
AppRoutingModule (excerpt)
content_copyimport { FirstComponent } from './first/first.component';
import { SecondComponent } from './second/second.component';
Defining a basic route
There are three fundamental building blocks to creating a route.
Import the AppRoutingModule into AppModule and add it to the imports array.
The Angular CLI performs this step for you. However, if you are creating an application manually or
working with an existing, non-CLI application, verify that the imports and configuration are correct. The
following is the default AppModule using the CLI with the --routing flag.
Default CLI AppModule with routing
content_copyimport { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module'; // CLI imports AppRoutingModule
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule // CLI adds AppRoutingModule to the AppModule's imports array
],
29
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
1. Import RouterModule and Routes into your routing module.
The Angular CLI performs this step automatically. The CLI also sets up a Routes array for your
routes and configures the imports and exports arrays for @NgModule().
CLI application routing module
content_copyimport { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; // CLI imports router
const routes: Routes = []; // sets up routes constant where you define your routes
31
Setting up redirects
To set up a redirect, configure a route with the path you want to redirect from, the component you want to
redirect to, and a pathMatch value that tells the router how to match the URL.
AppRoutingModule (excerpt)
content_copyconst routes: Routes = [
{ path: 'first-component', component: FirstComponent },
{ path: 'second-component', component: SecondComponent },
{ path: '', redirectTo: '/first-component', pathMatch: 'full' }, // redirect to `first-component`
{ path: '**', component: PageNotFoundComponent }, // Wildcard route for a 404 page
];
In this example, the third route is a redirect so that the router defaults to the first-component route. Notice
that this redirect precedes the wildcard route. Here, path: '' means to use the initial relative URL ('').
For more details on pathMatch see Spotlight on pathMatch.
Nesting routes
As your application grows more complex, you may want to create routes that are relative to a component
other than your root component. These types of nested routes are called child routes. This means you're
adding a second <router-outlet> to your app, because it is in addition to the <router-
outlet> in AppComponent.
In this example, there are two additional child components, child-a, and child-b.
Here, FirstComponent has its own <nav> and a second <router-outlet> in addition to the one
in AppComponent.
In the template
content_copy<h2>First Component</h2>
<nav>
<ul>
<li><a routerLink="child-a">Child A</a></li>
<li><a routerLink="child-b">Child B</a></li>
</ul>
</nav>
<router-outlet></router-outlet>
A child route is like any other route, in that it needs both a path and a component. The one difference is
that you place child routes in a children array within the parent route.
AppRoutingModule (excerpt)
content_copyconst routes: Routes = [
{
path: 'first-component',
component: FirstComponent, // this is the component with the <router-outlet> in the template
children: [
{
path: 'child-a', // child route path
component: ChildAComponent, // child route component that the router renders
},
{
path: 'child-b',
component: ChildBComponent, // another child route component that the router renders
},
],
},
];
Using relative paths
32
Relative paths allow you to define paths that are relative to the current URL segment. The following
example shows a relative route to another component, second-
component. FirstComponent and SecondComponent are at the same level in the tree, however, the link
to SecondComponent is situated within the FirstComponent, meaning that the router has to go up a level
and then into the second directory to find the SecondComponent. Rather than writing out the whole path
to get to SecondComponent, you can use the ../ notation to go up a level.
In the template
content_copy<h2>First Component</h2>
<nav>
<ul>
<li><a routerLink="../second-component">Relative Route to second component</a></li>
</ul>
</nav>
<router-outlet></router-outlet>
In addition to ../, you can use ./ or no leading slash to specify the current level.
Specifying a relative route
To specify a relative route, use the NavigationExtras relativeTo property. In the component class,
import NavigationExtras from the @angular/router.
Then use relativeTo in your navigation method. After the link parameters array, which here
contains items, add an object with the relativeTo property set to the ActivatedRoute, which is this.route.
RelativeTo
content_copygoToItems() {
this.router.navigate(['items'], { relativeTo: this.route });
}
The goToItems() method interprets the destination URI as relative to the activated route and navigates to
the items route.
Accessing query parameters and fragments
Sometimes, a feature of your application requires accessing a part of a route, such as a query parameter or
a fragment. The Tour of Heroes application at this stage in the tutorial uses a list view in which you can
click on a hero to see details. The router uses an id to show the correct hero's details.
First, import the following members in the component you want to navigate from.
Component import statements (excerpt)
content_copyimport { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
Next inject the activated route service:
Component (excerpt)
content_copyconstructor(private route: ActivatedRoute) {}
Configure the class so that you have an observable, heroes$, a selectedId to hold the id number of the
hero, and the heroes in the ngOnInit(), add the following code to get the id of the selected hero. This code
snippet assumes that you have a heroes list, a hero service, a function to get your heroes, and the HTML
to render your list and details, just as in the Tour of Heroes example.
Component 1 (excerpt)
content_copyheroes$: Observable;
selectedId: number;
heroes = HEROES;
ngOnInit() {
this.heroes$ = this.route.paramMap.pipe(
switchMap(params => {
this.selectedId = Number(params.get('id'));
return this.service.getHeroes();
})
33
);
}
Next, in the component that you want to navigate to, import the following members.
Component 2 (excerpt)
content_copyimport { Router, ActivatedRoute, ParamMap } from '@angular/router';
import { Observable } from 'rxjs';
Inject ActivatedRoute and Router in the constructor of the component class so they are available to this
component:
Component 2 (excerpt)
content_copyhero$: Observable;
constructor(
private route: ActivatedRoute,
private router: Router ) {}
ngOnInit() {
const heroId = this.route.snapshot.paramMap.get('id');
this.hero$ = this.service.getHero(heroId);
}
gotoItems(hero: Hero) {
const heroId = hero ? hero.id : null;
// Pass along the hero id if available
// so that the HeroList component can select that item.
this.router.navigate(['/heroes', { id: heroId }]);
}
Lazy loading
You can configure your routes to lazy load modules, which means that Angular only loads modules as
needed, rather than loading all modules when the application launches. Additionally, you can preload
parts of your application in the background to improve the user experience.
For more information on lazy loading and preloading see the dedicated guide Lazy loading NgModules.
Preventing unauthorized access
Use route guards to prevent users from navigating to parts of an application without authorization. The
following route guards are available in Angular:
● CanActivate
● CanActivateChild
● CanDeactivate
● Resolve
● CanLoad
To use route guards, consider using component-less routes as this facilitates guarding child routes.
Create a service for your guard:
content_copyng generate guard your-guard
In your guard class, implement the guard you want to use. The following example uses CanActivate to
guard the route.
Component (excerpt)
content_copyexport class YourGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
// your logic goes here
}
34
}
In your routing module, use the appropriate property in your routes configuration. Here, canActivate tells
the router to mediate navigation to this particular route.
Routing module (excerpt)
content_copy{
path: '/your-path',
component: YourComponent,
canActivate: [YourGuard],
}
For more information with a working example, see the routing tutorial section on route guards.
Link parameters array
A link parameters array holds the following ingredients for router navigation:
● The path of the route to the destination component.
● Required and optional route parameters that go into the route URL.
You can bind the RouterLink directive to such an array like this:
src/app/app.component.ts (h-anchor)
content_copy<a [routerLink]="['/heroes']">Heroes</a>
The following is a two-element array when specifying a route parameter:
src/app/heroes/hero-list/hero-list.component.html (nav-to-detail)
content_copy<a [routerLink]="['/hero', hero.id]">
<span class="badge">{{ hero.id }}</span>{{ hero.name }}
</a>
You can provide optional route parameters in an object, as in { foo: 'foo' }:
src/app/app.component.ts (cc-query-params)
content_copy<a [routerLink]="['/crisis-center', { foo: 'foo' }]">Crisis Center</a>
These three examples cover the needs of an application with one level of routing. However, with a child
router, such as in the crisis center, you create new link array possibilities.
The following minimal RouterLink example builds upon a specified default child route for the crisis
center.
src/app/app.component.ts (cc-anchor-w-default)
content_copy<a [routerLink]="['/crisis-center']">Crisis Center</a>
Note the following:
● The first item in the array identifies the parent route (/crisis-center).
36
You must add a <base href> element to the application's index.html for pushState routing to work. The
browser uses the <base href> value to prefix relative URLs when referencing CSS files, scripts, and
images.
Add the <base> element just after the <head> tag. If the app folder is the application root, as it is for this
application, set the href value in index.html as shown here.
src/index.html (base-href)
content_copy<base href="/">
HTML5 URLs and the <base href>
The guidelines that follow will refer to different parts of a URL. This diagram outlines what those parts
refer to:
content_copyfoo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
While the router uses the HTML5 pushState style by default, you must configure that strategy with
a <base href>.
The preferred way to configure the strategy is to add a <base href> element tag in the <head> of
the index.html.
src/index.html (base-href)
content_copy<base href="/">
Without that tag, the browser may not be able to load resources (images, CSS, scripts) when "deep
linking" into the application.
Some developers may not be able to add the <base> element, perhaps because they don't have access
to <head> or the index.html.
Those developers may still use HTML5 URLs by taking the following two steps:
1. Provide the router with an appropriate APP_BASE_HREF value.
2. Use root URLs (URLs with an authority) for all web resources: CSS, images, scripts, and template
HTML files.
● The <base href> path should end with a "/", as browsers ignore characters in the path that follow
the right-most "/".
● If the <base href> includes a query part, the query is only used if the path of a link in the page is
empty and has no query. This means that a query in the <base href> is only included when
using HashLocationStrategy.
● If a link in the page is a root URL (has an authority), the <base href> is not used. In this way,
an APP_BASE_HREF with an authority will cause all links created by Angular to ignore
the <base href> value.
● A fragment in the <base href> is never persisted.
For more complete information on how <base href> is used to construct target URIs, see the RFC section
on transforming references.
HashLocationStrategy
You can use HashLocationStrategy by providing the useHash: true in an object as the second argument of
the RouterModule.forRoot() in the AppModule.
src/app/app.module.ts (hash URL strategy)
content_copyimport { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(routes, { useHash: true }) // .../#/crisis-center/
],
declarations: [
AppComponent,
PageNotFoundComponent
],
providers: [
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Using Angular routes in a single-page application
This tutorial describes how you can build a single-page application, SPA that uses multiple Angular
routes.
In a Single Page Application (SPA), all of your application's functions exist in a single HTML page. As
users access your application's features, the browser needs to render only the parts that matter to the user,
instead of loading a new page. This pattern can significantly improve your application's user experience.
To define how users navigate through your application, you use routes. You can add routes to define how
users navigate from one part of your application to another. You can also configure routes to guard
against unexpected or unauthorized behavior.
To explore a sample application featuring the contents of this tutorial, see the live example / download
example.
Objectives
● Organize a sample application's features into modules.
41
Now when you open your application, it displays the heroes-list component by default.
Adding a 404 page
It is possible for a user to try to access a route that you have not defined. To account for this behavior, the
best practice is to display a 404 page. In this section, you'll create a 404 page and update your route
configuration to show that page for any unspecified routes.
1. From the terminal, create a new component, PageNotFound.
content_copyng generate component page-not-found
2. From your code editor, open the page-not-found.component.html file and replace its contents with
the following HTML.
src/app/page-not-found/page-not-found.component.html
content_copy<h2>Page Not Found</h2>
<p>We couldn't find that page! Not even with x-ray vision.</p>
3. Open the app.module.ts file. In the imports array, update the RouterModule section as follows.
src/app/app.module.ts
content_copyimports: [
BrowserModule,
RouterModule.forRoot([
{path: 'crisis-list', component: CrisisListComponent},
{path: 'heroes-list', component: HeroesListComponent},
{path: '', redirectTo: '/heroes-list', pathMatch: 'full'},
{path: '**', component: PageNotFoundComponent}
]),
],
The new route uses a path, **. This path is how Angular identifies a wildcard route. Any route
that does not match an existing route in your configuration will use this route.
Notice that the wildcard route is placed at the end of the array. The order of your routes is
important, as Angular applies routes in order and uses the first match it finds.
Try navigating to a non-existing route on your application, such as http://localhost:4200/powers. This
route doesn't match anything defined in your app.module.ts file. However, because you defined a
wildcard route, the application automatically displays your PageNotFound component.
Tutorial: Creating custom route matches
The Angular Router supports a powerful matching strategy that you can use to help users navigate your
application. This matching strategy supports static routes, variable routes with parameters, wildcard
routes, and so on. You can also build your own custom pattern matching for situations in which the URLs
are more complicated.
In this tutorial, you'll build a custom route matcher using Angular's UrlMatcher. This matcher looks for a
Twitter handle in the URL.
For a working example of the final version of this tutorial, see the live example / download example.
Create a sample application
Using the Angular CLI, create a new application, angular-custom-route-match. In addition to the default
Angular application framework, you will also create a profile component.
1. Create a new Angular project, angular-custom-route-match.
content_copyng new angular-custom-route-match
When prompted with Would you like to add Angular routing?, select Y.
When prompted with Which stylesheet format would you like to use?, select CSS.
After a few moments, a new project, angular-custom-route-match, is ready.
2. From your terminal, navigate to the angular-custom-route-match directory.
3. Create a component, profile.
content_copyng generate component profile
4. In your code editor, locate the file, profile.component.html and replace the placeholder content
with the following HTML.
src/app/profile/profile.component.html
content_copy<p>
Hello {{ username$ | async }}!
42
</p>
5. In your code editor, locate the file, app.component.html and replace the placeholder content with
the following HTML.
src/app/app.component.html
content_copy<h2>Routing with Custom Matching</h2>
<router-outlet></router-outlet>
Configure your routes for your application
With your application framework in place, you next need to add routing capabilities to
the app.module.ts file. As a part of this process, you will create a custom URL matcher that looks for a
Twitter handle in the URL. This handle is identified by a preceding @ symbol.
1. In your code editor, open your app.module.ts file.
2. Add an import statement for Angular's RouterModule and UrlMatcher.
src/app/app.module.ts
content_copyimport { RouterModule, UrlSegment } from '@angular/router';
3. In the imports array, add a RouterModule.forRoot([]) statement.
src/app/app.module.ts
content_copy@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot([
{
/* . . . */
])],
declarations: [ AppComponent, ProfileComponent ],
bootstrap: [ AppComponent ]
})
4. Define the custom route matcher by adding the following code to
the RouterModule.forRoot() statement.
src/app/app.module.ts
content_copymatcher: (url) => {
if (url.length === 1 && url[0].path.match(/^@[\w]+$/gm)) {
return {
consumed: url,
posParams: {
username: new UrlSegment(url[0].path.substr(1), {})
}
};
}
return null;
},
component: ProfileComponent
}
This custom matcher is a function that performs the following tasks:
● The matcher verifies that the array contains only one segment.
● The matcher employs a regular expression to ensure that the format of the username is a match.
● If there is a match, the function returns the entire URL, defining a username route parameter as a
substring of the path.
43
● If there isn't a match, the function returns null and the router continues to look for other routes that
match the URL.
A custom URL matcher behaves like any other route definition. You can define child routes or lazy
loaded routes as you would with any other route.
Subscribe to the route parameters
With the custom matcher in place, you now need to subscribe to the route parameters in
the profile component.
1. In your code editor, open your profile.component.ts file.
2. Add an import statement for Angular's ActivatedRoute and ParamMap.
src/app/profile/profile.component.ts
content_copyimport { ActivatedRoute, ParamMap } from '@angular/router';
3. Add an import statement for RxJS map.
src/app/profile/profile.component.ts
content_copyimport { map } from 'rxjs/operators';
4. Subscribe to the username route parameter.
src/app/profile/profile.component.ts
content_copyusername$ = this.route.paramMap
.pipe(
map((params: ParamMap) => params.get('username'))
);
5. Inject the ActivatedRoute into the component's constructor.
src/app/profile/profile.component.ts
content_copyconstructor(private route: ActivatedRoute) { }
Test your custom URL matcher
With your code in place, you can now test your custom URL matcher.
1. From a terminal window, run the ng serve command.
content_copyng serve
2. Open a browser to http://localhost:4200.
You should see a single web page, consisting of a sentence that reads Navigate to my profile.
3. Click the my profile hyperlink.
A new sentence, reading Hello, Angular! appears on the page.
Router Reference
The following sections highlight some core router concepts.
Router imports
The Angular Router is an optional service that presents a particular component view for a given URL. It
is not part of the Angular core and thus is in its own library package, @angular/router.
Import what you need from it as you would from any other Angular package.
src/app/app.module.ts (import)
content_copyimport { RouterModule, Routes } from '@angular/router';
For more on browser URL styles, see LocationStrategy and browser URL styles.
Configuration
A routed Angular application has one singleton instance of the Router service. When the browser's URL
changes, that router looks for a corresponding Route from which it can determine the component to
display.
A router has no routes until you configure it. The following example creates five route definitions,
configures the router via the RouterModule.forRoot() method, and adds the result to
the AppModule's imports array.
src/app/app.module.ts (excerpt)
content_copyconst appRoutes: Routes = [
{ path: 'crisis-center', component: CrisisListComponent },
{ path: 'hero/:id', component: HeroDetailComponent },
{
path: 'heroes',
44
component: HeroListComponent,
data: { title: 'Heroes List' }
},
{ path: '',
redirectTo: '/heroes',
pathMatch: 'full'
},
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(
appRoutes,
{ enableTracing: true } // <-- debugging purposes only
)
// other imports here
],
...
})
export class AppModule { }
The appRoutes array of routes describes how to navigate. Pass it to the RouterModule.forRoot() method
in the module imports to configure the router.
Each Route maps a URL path to a component. There are no leading slashes in the path. The router parses
and builds the final URL for you, which allows you to use both relative and absolute paths when
navigating between application views.
The :id in the second route is a token for a route parameter. In a URL such as /hero/42, "42" is the value
of the id parameter. The corresponding HeroDetailComponent uses that value to find and present the hero
whose id is 42.
The data property in the third route is a place to store arbitrary data associated with this specific route.
The data property is accessible within each activated route. Use it to store items such as page titles,
breadcrumb text, and other read-only, static data. You can use the resolve guard to retrieve dynamic data.
The empty path in the fourth route represents the default path for the application—the place to go when
the path in the URL is empty, as it typically is at the start. This default route redirects to the route for
the /heroes URL and, therefore, displays the HeroesListComponent.
If you need to see what events are happening during the navigation lifecycle, there is
the enableTracing option as part of the router's default configuration. This outputs each router event that
took place during each navigation lifecycle to the browser console. Use enableTracing only for debugging
purposes. You set the enableTracing: true option in the object passed as the second argument to
the RouterModule.forRoot() method.
Router outlet
The RouterOutlet is a directive from the router library that is used like a component. It acts as a
placeholder that marks the spot in the template where the router should display the components for that
outlet.
content_copy<router-outlet></router-outlet>
<!-- Routed components go here -->
Given the configuration above, when the browser URL for this application becomes /heroes, the router
matches that URL to the route path /heroes and displays the HeroListComponent as a sibling element to
the RouterOutlet that you've placed in the host component's template.
Router links
To navigate as a result of some user action such as the click of an anchor tag, use RouterLink.
Consider the following template:
src/app/app.component.html
content_copy<h1>Angular Router</h1>
45
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
The RouterLink directives on the anchor tags give the router control over those elements. The navigation
paths are fixed, so you can assign a string to the routerLink (a "one-time" binding).
Had the navigation path been more dynamic, you could have bound to a template expression that returned
an array of route link parameters; that is, the link parameters array. The router resolves that array into a
complete URL.
Active router links
The RouterLinkActive directive toggles CSS classes for active RouterLink bindings based on the
current RouterState.
On each anchor tag, you see a property binding to the RouterLinkActive directive that looks
like routerLinkActive="...".
The template expression to the right of the equal sign, =, contains a space-delimited string of CSS classes
that the Router adds when this link is active (and removes when the link is inactive). You set
the RouterLinkActive directive to a string of classes such as [routerLinkActive]="'active fluffy'" or bind it
to a component property that returns such a string.
Active route links cascade down through each level of the route tree, so parent and child router links can
be active at the same time. To override this behavior, you can bind to the [routerLinkActiveOptions] input
binding with the { exact: true } expression. By using { exact: true }, a given RouterLink will only be
active if its URL is an exact match to the current URL.
Router state
After the end of each successful navigation lifecycle, the router builds a tree of ActivatedRoute objects
that make up the current state of the router. You can access the current RouterState from anywhere in the
application using the Router service and the routerState property.
Each ActivatedRoute in the RouterState provides methods to traverse up and down the route tree to get
information from parent, child, and sibling routes.
Activated route
The route path and parameters are available through an injected router service called the ActivatedRoute.
It has a great deal of useful information including:
Property Description
46
the query parameter.
Two older properties are still available; however, their replacements are preferable as they may be
deprecated in a future Angular version.
● params: An Observable that contains the required and optional parameters specific to the route.
Use paramMap instead.
● queryParams: An Observable that contains the query parameters available to all routes.
Use queryParamMap instead.
Router events
During each navigation, the Router emits navigation events through the Router.events property. These
events range from when the navigation starts and ends to many points in between. The full list of
navigation events is displayed in the table below.
47
URL and the routes are recognized.
When you enable the enableTracing option, Angular logs these events to the console. For an example of
filtering router navigation events, see the router section of the Observables in Angular guide.
Router terminology
Here are the key Router terms and their meanings:
48
Router Part Meaning
49
Routing An Angular component with a RouterOutlet that
component displays views based on router navigations.
src\app\app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
As you can see in the above root NgModule, the class is decorated with @NgModule.
The @NgModule decorator is a function that takes a single metadata object. The
properties of the metadata object describe the module. The following are important
properties:
50
limited to within the module until you export them in the exports array of
NgModule.
exports - The exports property is used to make the subsets of declarations visible
and usable in the component templates of other NgModules.
imports - The imports property is used to import an array of other modules whose
classes are required by component templates that are declared in this MgModule.
providers - The providers property is used to declare an array of services to make
them available for dependency injection throughout the application. The providers
can also be specified at the component level.
bootstrap - The bootstrap property is used to tell Angular which component view
to load as the top-level component when the application starts. The bootstrap
property should only be set by the root NgModule.
A root NgModule always has one root component that is generated during project
creation. However, any NgModule can have any number of extra components, which
can be loaded through the router or created through the template.
A module in Angular can be created using the Angular CLI command as follows:
ng generate module module-name
src/app/user-auth/user-auth.module.ts
51
import { CommonModule } from '@angular/common';
@NgModule({
declarations: [],
imports: [
CommonModule
]
})
export class UserAuthModule { }
src/app/product/product.module.ts
@NgModule({
declarations: [],
imports: [
CommonModule
]
})
export class ProductModule { }
Why Services?
Components should never directly fetch or save data. They should concentrate on data
presentation and delegate data access to a service.
52
Services make sharing of information among classes that do not know each other
easier.
By removing data access from components, we can change the implementation at any
time without having to touch any components. They have no idea how the service
operates.
Creating a Service
To create a service in Angular, you can use the Angular CLI command as shown in the
example below:
ng generate service User
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor() { }
}
53