DEV Community


Posted on • Updated on


Hello everyone,

in today's article, I wanted to briefly illustrate one of the features of Angular that has left me pleasantly satisfied: the Inject function.

Note: All the code used in this article can be found here.


Introduction to Inheritance in TypeScript

Before delving into the explanation of the Inject function, I wanted to briefly touch on inheritance in TypeScript. Inheritance is a process in OOP that allows us to extend our classes by inheriting methods and fields from other classes. In TypeScript, you can achieve this using the extends keyword, like this:

interface IAnimal {
  dateOfBirth: any;

interface IDog extends IAnimal {
  breed: any;

class Animal {
  resident: IAnimal ;
  constructor(animal: IAnimal) {
    this.resident = animal;

class Dog extends Animal {
  constructor(dog: IDog, private parameter2: number) {

Enter fullscreen mode Exit fullscreen mode

As you can see in the constructor of the Dog class, if we want to inject or add additional dependencies in the constructor of the child class, we must necessarily use the super function and inject the inherited dependencies from the base class into it. Of course, this means that if the Animal class had 10 dependencies, we would need to inject all 10 dependencies in the super call.

The Inject function

Once we have a good understanding of inheritance in TypeScript, we can introduce the first benefit of using the new Inject feature in Angular, which precisely relates to not having to use the super function to inherit dependencies from a parent class. Let's take the example of a basic service:

// base-service.service.ts
export abstract class BaseService {
  http: HttpClient = inject(HttpClient);

// user.service.ts
  providedIn: 'root',
export class UserService extends BaseService {
  getAll() {
    return this.http.get<User[]>('/users');

Enter fullscreen mode Exit fullscreen mode

as you can see, instead of inserting dependencies inside the constructor, we have simply created a variable of type protected, which will then be inherited by child classes.

Another benefit also relates to the use of inject outside of a component or service class. It could be used, for example, to create a function that dynamically retrieves a router param like this:

import { inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

export function getRouteParameter(param: string) {
  const router = inject(ActivatedRoute);
  return router.snapshot.paramMap.get(param);

Enter fullscreen mode Exit fullscreen mode

to then be used in

import { CommonModule } from '@angular/common';
import { Component, inject, OnInit } from '@angular/core';
import { RouterLink } from '@angular/router';
import { getRouteParameter } from '../../utility';
import { User } from '../user.model';
import { UserService } from '../user.service';
import { Observable } from 'rxjs';
import { UserAddressPipe } from '../../user-address.pipe';

  selector: 'app-user-detail',
  standalone: true,
  imports: [CommonModule, RouterLink, UserAddressPipe],
  providers: [UserService],
  templateUrl: './user-detail.component.html',
export class UserDetailComponent implements OnInit {
  userId: string | null = '';
  user$!: Observable<User>;
  private userService: UserService = inject(UserService);
  constructor() {
    this.userId = getRouteParameter('id');
  ngOnInit(): void {
    if (this.userId != null)
      this.user$ = this.userService.getById(+this.userId);

Enter fullscreen mode Exit fullscreen mode

making the HTTP call from the service in this way.

And with that, we can conclude our brief overview of the inject function and its uses. If you found this article helpful, please consider sharing it and leaving a review ❤️.

Happy Coding!!

Top comments (0)