Dependency Injection in Angular

Deep Gautam  Print 
26 Nov 2018
 
Intermediate
137

Dependency injection is the core feature of Angular, be it angularjs or Angular. 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 very good manner. In simple terms dependency injection means injecting the dependency, here in case of Angular we are injecting the dependency in components.

Goals

  1. Learn Injectors.

  2. DI Providers.

  3. DI in action with example.

Specifications

If you have no idea what service is in Angular then I would suggest go and read this article for 3 minutes Exploring Angular Services. It is the 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 few components or in many components or in 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 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() { }
 }

First thing if you noticed Injectable has been imported from @angular/core and second thing @injectable has been used default in service. So now we understood Injectable is main ingredients 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 actually inject it anywhere until you configure an Angular dependency injector with a provider of that service.

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 own providers with every injector, for services that Angular defines. You can register your own providers for services that your app needs. If you noticed In above-created service then you can see default implementation of service is it is provided in root. SO now you might be having the questions where all service can be as provider :

  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 application so if you want to use those services in 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 3 mentioned above), third inject service in component using constructor dependency injection.

Let say I have 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 screen shot image :
Summary

So dependency injection is angular is so simple and what all we have done is we have created a class which has @injectable attribute and we have created a component, assigned a provider and injected the service in component. Hope you like the concept, please comment your question if any doubt or discussion needed.

Crack Your Technical Interview

 
Join Our Hands-on Training Programs
+