Injectable Decorators & Tree shakable Providers in Angular

Written by neerajdana | Published 2019/02/06
Tech Story Tags: angular2 | software-development | javascript | development | angular

TLDRvia the TL;DR App

In this article, we will see how to handle injectables in Angular in more detail.

We have seen before how our services are being registered in the Angular dependency system — you can read about it here. You will notice that in our service did not use any decorator for services, such as an Injectable.

Now let us suppose we have two services one of them is SQLService, and the other is an Oracle service. We have registered both the services in the app component level and notice we are using SQL service in app component.

import { Component } from '@angular/core';

export class SQLService {
  constructor() {
    console.log("SQLService")
  }
}

export class OracleService {
  constructor() {
    console.log("OracleService")
  }
}
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [OracleService, SQLService]
})
export class AppComponent {
  constructor(private service: SQLService) {
    console.log(this.service)
  }
  name = 'Angular';
}

Until this point, everything looks right if you will execute it will show the output as

Angular will only provide the instance of the service if it was requested somewhere else it wont create the instances of dependencies for example if we remove the constructor of app component it will not instantiate the sqlservice instance

Now let’s open the dev tools and go to the source tab and see the main.js file over there and search for oracle keyword as shown in the image below.

So we will see although we are not using Oracle service anywhere in our code then also it’s been included in the main bundle on angular which increases the size of the primary packet and is directly proportional to the speed of our app.

So the conclusion is that only those files should be included in the main bundle which is required or demanded as the dependency by other pieces.

In solving this problem, Injectable comes into the picture. So iI highly recommends reading my last article if you are not already familiar with the configuration object required to register a service in Angular.

So we have looked to provide a property which is an instance of the injection token which helps Angular to identify our dependency uniquely. The other one is auseFactory, function responsible for creating the instance of our dependency and whichdeps is an array which contains all sub-dependencies if it exists.

We will now remove both the services from our providers array and decorate the services with an injectable decorator who also accepts a configuration object similar to providers configuration object so let’s have a look at it:

In this object, there is a mandatory property that is whichprovidedIn is by default “root.”

the other property is useFactory which will a function responsible for creating the object of our dependency so now our code will look something like this:

app.Component.ts

import { Component, Injectable } from '@angular/core';
import { SQLService } from './service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  constructor(private service: SQLService) { }
  name = 'Angular';
}

sqlservice.ts

import { Injectable } from '@angular/core';

@Injectable({
    providedIn:'root',
    useFactory : ()=>new SQLService()
  })
export class SQLService {
  constructor() {
    console.log("SQLService")
  }
}

oraclseservice.ts

import { Injectable } from '@angular/core';

@Injectable({
    providedIn:'root',
    useFactory : ()=>new OracleService()
  })
export class OracleService {
  constructor() {
    console.log("OracleService")
  }
}

Now you can see that we have injected the SQL service into our app component and we are not using the Oracle service so let us go to the main.js in the source tab of our browser Dev Tools and search for SQL and Oracle. We will see that we have 0 occurrences of Oracle and some occurrences of SQL.

This kind of on-demand provider is known as a Tree Shakable provider, used by Angular’s dependency injection system in a way that can improve the performance of an Angular application.

Don’t hesitate to clap or follow if you learn something new. Thanks!

An introduction to Angular dependency injection


Published by HackerNoon on 2019/02/06