Skip to content
Angular Essentials
GitHub

Injecting dependency (@Inject)

The most common way to inject a dependency is to declare it in a class constructor. When Angular creates a new instance of a component, directive, or pipe class, it determines which services or other dependencies that class needs by looking at the constructor parameter types. For example, if the AppComponent needs the AuthService, the constructor can look like this:

@Inject() is a manual mechanism for letting Angular know that a parameter must be injected. It can be used like so:

@Component({  })
class AppComponent {
  constructor(@Inject(AuthService) private readonly authService) {}
}

In the above we’ve asked for authService to be the singleton Angular associates with the class symbol AuthService by calling @Inject(AuthService). It’s important to note that we’re using AuthService for its typings and as a reference to its singleton. We are not using AuthService to instantiate anything, Angular does that for us behind the scenes.

When using TypeScript, @Inject is only needed for injecting primitives. TypeScript’s types let Angular know what to do in most cases. The above example would be simplified in TypeScript to:

@Component({  })
class AppComponent {
  constructor(private readonly authService: AuthService) {}
}

The following syntax can also be used to inject dependency instead of constructor.

@Component({  })
class AppComponent {
  private readonly authService = inject(AuthService);
}

When Angular discovers that a component depends on a service, it first checks if the injector has any existing instances of that service. If a requested service instance doesn’t yet exist, the injector creates one using the registered provider and adds it to the injector before returning the service to Angular.

When all requested services have been resolved and returned, Angular can call the component’s constructor with those services as arguments.

Inject AuthService using constructor of HeaderComponent.

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {

  private readonly authService = inject(AuthService);

  ngOnInit(): void {
  }
}

Create a button called Authenticate which will simply call authenticate() of AuthService.

<!--header.component.html-->
<mat-toolbar color="primary">
    <span>Angular Basic</span>
    <button mat-button routerLink="/grocery">Grocery</button>
    <button mat-button routerLink="/sports">Sports</button>
    <span class="spacer"></span>
    <button (click)="login()" mat-icon-button aria-label="login">
      <mat-icon>login</mat-icon>
    </button>
</mat-toolbar>
// header.component.ts
@Component({
  selector: 'app-header',
  standalone: true,
  imports: [
    CommonModule,
    MatToolbarModule,
    MatMenuModule,
    MatButtonModule,
    RouterModule,
    MatIconModule
  ],
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent {

  private readonly authService = inject(AuthService);

  login(): void {
    this.authService.authenticate();
  }
}
// header.component.scss
mat-toolbar {
  margin-bottom: 10px;
}

.spacer {
  flex: 1 1 auto;
}