Leveraging Dependency Injection in Angular to Simplify HTTP Calls

When developing Angular applications, managing HTTP requests efficiently is a common challenge. To streamline this process, you might create a common class for making API calls, which can then be extended by other components. However, dependency injection (DI) in Angular can introduce complications, particularly when extending classes that require injected services.

In this post, we'll walk through a scenario where we have a common class for making HTTP calls and explore how to use Angular's new inject() function to simplify the DI process.

Creating a Common Class for HTTP Calls
First, let's create a common class, HTTPClass, which will manage our HTTP requests. This class will use Angular's HttpClient service to make GET and POST requests. Instead of using the constructor to inject HttpClient, we'll use the inject() function directly in the class.

  import { HttpClient } from "@angular/common/http";

  export class HTTPClass{
    constructor(
      private _httpClient: HttpClient
    ){}
  
    public postAPICall(){
      // make api call
    }
  
    public getAPICall(){
      // make api call
    }
  }

Extending the Common Class
Next, in AppComponent class that extends HttpClient. By using the inject() function in the HTTPClass, to avoid the need to pass HttpClient from the AppComponent constructor to the HTTPClass constructor, simplifying the dependency injection process.

      import { Component } from '@angular/core';
      import { AppService } from './app.service';
      import { HTTPClass } from './http.class';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
      })
      export class AppComponent extends HTTPClass {
      
        constructor(private _appService: AppService) {
          super();
        }
      }
    
Now when using constructor in HTTPClass to inject HttpClient service gives the above error because now it is expecting an argument of type HttpClient, so to avoid this error or issue we'll make use of angular inject() function to inject service in HTTPClass


Updated HTTPClass

    import { HttpClient } from "@angular/common/http";
    import { inject } from "@angular/core";
    
    export class HTTPClass{
      private _httpClient: HttpClient = inject(HttpClient);
    
      public postAPICall(){
        // make api call
      }
    
      public getAPICall(){
        // make api call
      }
    }
  
But What is inject() ?
Angular's inject() function, introduced in Angular 14, allows you to inject dependencies directly where needed, bypassing the need to pass them through constructors. This makes your code cleaner and easier to maintain.

In the example above, the inject() function is used to inject HttpClient directly into the HTTPClass as a class property. This approach eliminates the need to pass HttpClient from the AppComponent constructor, simplifying the dependency injection process.


Conclusion
Using Angular's inject() function can greatly simplify dependency injection, especially when working with common classes that are extended by multiple components. By adopting this approach, you can make your code more maintainable and reduce the boilerplate associated with passing dependencies through constructors.

In our example, we demonstrated how to refactor a common class for making HTTP calls to use the inject() function, making the extension of this class by other components much simpler. This technique can be applied to other services and dependencies in your Angular application, helping you to write cleaner and more efficient code.

Comments

Popular posts from this blog

Custom Validator to match Password and Confirm Password in Angular

Enhancing Express.js Requests with TypeScript: Adding User Objects and More

How to Avoid Page Changes When You Have Unsaved Changes in Angular