DEV Community

Cover image for Migration to the `inject` function in components,...
Amin-Karimi
Amin-Karimi

Posted on

Migration to the `inject` function in components,...

Angular 18 has introduced a powerful and flexible feature: the inject() function. This function redefines how dependency injection (DI) works in Angular, making it more intuitive, especially in complex scenarios. Let's dive into how this function works, why it's a game-changer, and how you can use it with examples straight from the official Angular documentation.

Command for Migration(Angular 18.2)

ng generate @angular/core:inject
Enter fullscreen mode Exit fullscreen mode

What is the inject() Function?

Traditionally, Angular's DI relied heavily on constructor injection. You'd typically declare dependencies in a class constructor, and Angular would resolve them for you:
Before:

typescript

import { HttpClient } from '@angular/common/http';
export class test {
constructor(private http: HttpClient) {}
}
Enter fullscreen mode Exit fullscreen mode

While this works perfectly fine, it has limitations—especially when working with services that require conditional or dynamic instantiation.

The inject() function, however, allows you to inject dependencies directly within a function or method, bypassing the constructor. This is particularly useful in standalone functions or in scenarios where the dependency isn’t needed until later in the method logic.

How to Use inject()?

Here’s a simple example. Let's say you have a service MyService that you want to use in a function outside of a class:

typescript

import { inject } from '@angular/core';
import { MyService } from './my-service';

@Component()
export class MyComp {
  myService = inject(MyService);

test() {
  myService.doSomething();
}
}
Enter fullscreen mode Exit fullscreen mode

In this example, inject(MyService) retrieves the instance of MyService just like it would if it were injected in a constructor. This makes the inject() function highly versatile for various scenarios, including utility functions or deeply nested services.

Advanced Example: Injecting with Custom Options

Angular’s inject() also supports advanced use cases where you might need to pass additional options. For instance, suppose you want to inject a service with a fallback value if the service isn't provided:

typescript

import { inject } from '@angular/core';
import { MyService } from './my-service';

@Component()
export class MyComp {
 private  myService = inject(MyService, { optional: true });
}
Enter fullscreen mode Exit fullscreen mode

Why Should You Care?

  • Improved Flexibility: inject() provides more control over when and how dependencies are injected.
  • Better Readability: Dependencies are now more explicitly tied to their usage.
  • Enhanced Performance: Conditional and lazy loading of dependencies can reduce memory footprint and improve load times.

Angular 18's inject() function is not just a minor update—it's a fundamental shift in how you can write, manage, and optimize your Angular applications. By using this new approach, you can write cleaner, more efficient, and more maintainable code.

Top comments (2)

Collapse
 
jangelodev profile image
João Angelo

Hi Amin-Karimi,
Top, very nice and helpful !
Thanks for sharing.

Collapse
 
aminkarimi_sis profile image
Amin-Karimi

Hi João Angelo,
Thank you! I'm glad you found it helpful.