Introduction
In this article, we are going to explore the steps needed to create services in Angular applications along with the concept of dependency injection.
What is dependency Injection and why do we use it?
Dependency Injection (DI) is a mechanism where the required resources will be injected into the code automatically. Angular comes with an in-built dependency injection subsystem.
- DI allows developers to reuse the code across applications.
- DI makes application development and testing much easier.
- DI makes the code loosely coupled.
- DI allows the developer to ask for the dependencies from Angular. There is no need for the developer to explicitly create/instantiate them.
What is Service and why do we use it?
- A service in Angular is a class that contains some functionality that can be reused across the application. A service is a singleton object. Angular services are a mechanism for abstracting shared code and functionality throughout the application.
- Angular Services come as objects that are wired together using dependency injection.
- Angular provides a few inbuilt services. We can also create custom services.
Why Services?
- Services can be used to share the code across components of an application.
- Services can be used to make HTTP requests.
Creating a Service
Create a service class using the following command.
ng generate service Article
The above command will create a service class (article.service.ts) as shown below.
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ArticleService {
constructor() { }
}
@Injectable() decorator makes the class injectable into application components.
Providing a Service
Services can be provided in Angular applications in any of the following ways.
The first way to register the service is to specify the provided property using @Injectable decorator. This property is added by default when you generate a service using Angular CLI.
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ArticleService {
constructor() { }
}
Line 4. provided property registers article service at the root level (app module).
When the ArticleService is provided at the root level, Angular creates a singleton instance of the service class and injects the same instance into any class that uses this service class. In addition, Angular also optimizes the application if registered through providedIn property by removing the service class if none of the components use it.
There is also a way to limit the scope of the service class by registering it in the providers' property inside the @Component decorator. Providers in component decorator and module decorator are independent. Providing a service class inside component creates a separate instance for that component and its nested components.
Add the below code in app.components.ts,
import { Component } from '@angular/core';
import { ArticleService } from './article.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [ArticleService]
})
export class AppComponent {
title = 'FormsProject';
}
Services can also be provided across the application by registering it using the provider's property in the @Ngmodule decorator of any module.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
import { ArticleFormComponent } from './article-form/article-form.component';
import { RegistrationFormComponent } from './registration-form/registration-form.component';
import { ArticleService } from './article.service';
@NgModule({
declarations: [
AppComponent,
ArticleFormComponent,
RegistrationFormComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule
],
providers: [ArticleService],
bootstrap: [AppComponent]
})
export class AppModule { }
Line 22. When the service class is added to the provider's property of the root module, all the directives and components will have access to the same instance of the service.
Injecting a Service
The only way to inject a service into a component/directive or any other class is through a constructor. Add a constructor in a component class with a service class as an argument as shown below.
Here, ArticleService will be injected into the component through constructor injection by the framework.
import { Component } from '@angular/core';
import { ArticleService } from './article.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [ArticleService]
})
export class AppComponent {
title = 'FormsProject';
constructor(private articleService: ArticleService) {}
}
Problem Statement
Create an Article Component that fetches article details like id, and name and displays them on the page in a list format. Store the article details in an array and fetch the data using a custom service.
Demosteps
Create ArticleComponent by using the following CLI command.
ng generate component Article
Create a file with the name Article.ts under the book folder and add the following code.
export class Article {
id: number;
name: string;
}
Create a file with the name Article-data.ts under the book folder and add the following code.
import { Article } from './Article';
export var ARTICLES: Article[] = [
{ "id": 1, "name": "Angular Basic" },
{ "id": 2, "name": "Template in Angular" },
{ "id": 3, "name": "Nested component" },
{ "id": 4, "name": "Reactive component" },
{ "id": 5, "name": "Change detection technique" }
];
Create a service called ArticleService under the book folder using the following CLI command.
ng generate service Article
Add the following code in article.service.ts.
import { Injectable } from '@angular/core';
import { ARTICLES } from './Article-data';
import { Article } from './Article';
@Injectable({
providedIn: 'root'
})
export class ArticleService {
getArticles() {
return ARTICLES;
}
}
Add the following code in the article.component.ts file.
import { Component, OnInit } from '@angular/core';
import { ArticleService } from './article.service';
import { Article } from './Article';
@Component({
selector: 'app-article',
templateUrl: './article.component.html',
styleUrls: ['./article.component.css']
})
export class ArticleComponent implements OnInit {
articles: Article[];
constructor(private articleService: ArticleService) { }
getArticles() {
this.articles = this.articleService.getArticles();
}
ngOnInit() {
this.getArticles();
}
}
Write the below-given code in article.component.html.
<h2>My Articles</h2>
<ul class="Articles">
<li *ngFor="let article of Articles">
<span class="badge">{{article.id}}</span> {{article.name}}
</li>
</ul>
Add the following code in article.component.css which has styles for books.
.Articles {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.Articles li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.Articles li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.Articles .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}
Add the following code in app.component.html.
<app-article></app-article>
Save the files and check the output in the browser.
Summary
In this article, we explored the steps needed to create the services in Angular applications along with the concept of dependency injection. Hope you like the article. Until next time. Happy Reading!