Browse Articles

Dependency Injection in Angular

 Print   5 min read  
22 Jul 2022
Advanced
9.23K Views

Dependency injection is the core feature of Angular, be it AngularJs or Angular. The dependency injection concept has been very popular across software development paradigms and the google developers are well versed with such concept and they have boarded this concept in a very good manner. In simple terms, dependency injection means injecting the dependency, here in the case of Angular we are injecting the dependency in components.

The Angular uses Dependency Injection (DI) design to work efficiently that allows our components, classes, and modules to be inter-dependent while maintaining consistency over external dependencies injected in our applications. Thus, reducing the frequency with which the class/module-based changes.

In other words, the Angular Dependency Injection (DI) aims to decouple the implementation of services from the components. which simplify various processes such as testing, overriding, and altering the injected services without affecting the components dependent on these services.

Goals

  1. Learn Injectors.

  2. DI Providers.

  3. DI in action for example.

Specifications

If you have no idea what service is in Angular then I would suggest going and reading this article for 3 minutes Exploring Angular Services. It is a good explanation about services.

Why Dependency Injection is popular in Angular?

Because of Services

Services is the concept in Angular which is meant to deal with HTTP data or any common data which suppose to be shared across a few components or in many components or multiple modules.

Because of Constructor Dependency Injection

If you don't know what is constructor dependency injection then don't worry, I will explain but just remember, dependency injection in Angular is popular because of the very easy way of constructor dependency injection in Angular. So here first let us understand these two important terms: Injectors and Providers, My earlier created service source code, let us watch it closely.

 
 import { Injectable } from '@angular/core';
 
 @Injectable({
 providedIn: 'root'
 })
 export class DateTimeService {
 
 constructor() { }
 }

The first thing you noticed Injectable has been imported from @angular/core and the second thing @injectable has been used default in service. So now we understood Injectable is the main ingredient of dependency injection. The class we have created provides a service. The @Injectable() decorator marks it as a service that can be injected, but Angular can't inject it anywhere until you configure an Angular dependency injector with a provider of that service.

A provider is an object that implements one of the Provider interfaces. A provider object defines how to obtain an injectable dependency associated with a DI token. An injector uses the provider to create a new instance of a dependency for a class that requires it. Angular registers its providers with every injector, for services that Angular defines. You can register your providers for services that your app needs. If you noticed In the above-created service then you can see default implementation of the service is it is provided in the root. SO now you might be having the questions where all services can be as providers:

  1. In Component as below

  2.  @Component({
     selector: 'app-productdisplay',
     templateUrl: './productdisplay.component.html',
     styleUrls: ['./productdisplay.component.scss'],
     providers:[ProductService]
     })
    
  3. In Module (@NgModule)

  4.  import { BrowserModule } from '@angular/platform-browser';
     import { NgModule } from '@angular/core';
     import {NgbModule} from '@ng-bootstrap/ng-bootstrap'
     import { HttpClient,HttpClientModule } from '@angular/common/http';
     import {FormsModule,ReactiveFormsModule,Validators,FormControl,FormGroup,FormBuilder} from '@angular/forms';
     
     import { AppRoutingModule } from './app-routing.module';
     import { AppComponent } from './app.component';
     import { ProfileComponent } from './profile/profile.component';
     import { AdminComponent } from './admin/admin.component';
     import { DashboardComponent } from './dashboard/dashboard.component';
     import { ProductdisplayComponent } from './productdisplay/productdisplay.component';
     import { MycartComponent } from './mycart/mycart.component';
     import { ProductService } from './Services/product.service';
     
     @NgModule({
     declarations: [
     AppComponent,
     ProfileComponent,
     AdminComponent,
     DashboardComponent,
     ProductdisplayComponent,
     MycartComponent,
     ],
     imports: [
     BrowserModule,NgbModule,FormsModule,ReactiveFormsModule,HttpClientModule,
     AppRoutingModule
     ],
     providers: [ProductService],
     bootstrap: [AppComponent]
     })
     export class AppModule { }
    
  5. In sub-module: So if you have different modules in the application so if you want to use those services in a particular module then you can inject them in submodules.

Dependency Injection in Action

First, you create a service, second, you assign a provider(it can be one of them out of the 3 mentioned above), third inject service in component using constructor dependency injection.

Let's say I have the below service:
 
 import { Injectable } from '@angular/core';
 import { HttpClient,HttpClientModule, HttpHeaders } from '@angular/common/http';
 import { Http, Response } from '@angular/http'; 
 import { Observable, of, throwError, pipe} from "rxjs"
 import { map, filter, catchError, mergeMap } from 'rxjs/operators';
 import { AuthenticationService } from './authentication.service';
 import { Product } from '../Models/Product.Model';
 
 @Injectable({
 providedIn: 'root'
 })
 export class ProductService {
 
 public apiURL:string="http://localhost:50148/api/Products";
 constructor(private httpClient:HttpClient, private authService:AuthenticationService) { }
 
 getAllProducts ()
 {
 return this.httpClient.get(this.apiURL)
 .pipe(
 map(res => res),
 catchError( this.errorHandler)
 );
 }
 addProductToCart(prodcuts: any) {
 localStorage.setItem("product", JSON.stringify(prodcuts));
 }
 getProductFromCart() {
 //return localStorage.getItem("product");
 return JSON.parse(localStorage.getItem('product'));
 }
 removeAllProductFromCart() {
 return localStorage.removeItem("product");
 }
 errorHandler(error: Response) { 
 console.log(error); 
 return throwError(error); 
 }
 }
Here is my component code which is utilizing the service see how:
 import { Component, EventEmitter, Output,OnInit } from '@angular/core';
 import { ProductDisplay } from '../Models/ProductDisplay.Model';
 
 import { ProductService } from '../Services/product.service';
 import { Product } from '../Models/Product.Model';
 import { IAlert } from '../Models/IAlert';
 import { SharedService } from '../Services/shared.service';
 
 @Component({
 selector: 'app-productdisplay',
 templateUrl: './productdisplay.component.html',
 styleUrls: ['./productdisplay.component.scss'],
 providers:[ProductService]
 })
 export class ProductdisplayComponent implements OnInit {
 
 public alerts: Array<IAlert> = [];
 cartItemCount: number = 0;
 @Output() cartEvent = new EventEmitter<number>();
 allProducts: ProductDisplay[];
 productAddedTocart:Product[];
 constructor(private productService:ProductService,private sharedService:SharedService) { }
 
 ngOnInit() {
 this.productService.getAllProducts()
 .subscribe((result) => {
 this.globalResponse = result; 
 },
 error => { //This is error part
 console.log(error.message);
 },
 () => {
 // This is Success part
 console.log("Product fetched sucssesfully.");
 //console.log(this.globalResponse);
 this.allProducts=this.globalResponse;
 }
 )
 
 }
So how it is working just look at below screenshot image :
Summary

So dependency injection is angular is so simple and all we have done is have created a class that has @injectable attribute and we have created a component, assigned a provider, and injected the service in the component. Angular 2 to 13 training programs enable you to develop the front-end with .net MVC and Node.js. Hope you like the concept, please comment your question if any doubt or discussion is needed.

Learn to Crack Your Technical Interview

Accept cookies & close this