liveBook · Manning

Inject function

As explained in Modern Angular

The inject function is Angular's public API for retrieving a dependency from the active dependency-injection context.

Angular’s inject function retrieves the value provided for a dependency token without requiring constructor parameters. Publicly available since Angular v14, it loosens the former class-centered dependency-injection pattern: services, configuration tokens, and other DI values can be requested from functions as well as decorated classes. This makes small, composable helpers practical instead of forcing every consumer to receive a service or value as an argument. section 1.4.4 section 3.6

Use inject(Token) where Angular has an injection context. In a component or service, assigning its result to a field replaces constructor injection while avoiding an otherwise empty constructor, parameter access modifiers, and some repetitive wiring. Keep injected services private readonly where appropriate, even though field-based injection does not require constructor visibility syntax. section 3.2.1 section 3.2.4

Inject a service into a component

An employee list can declare employeeService = inject(EmployeeService) and then initialize employees$ from employeeService.getEmployees(). The component still receives the same dependency; only the declaration style changes from a constructor parameter to a field initializer. section 3.2.1

The larger payoff is functional composition. A helper can inject AuthService and expose only its authentication Observable, rather than handing every caller the full service. A footer can then call that helper for conditional rendering. This approach lets shared functions present a narrow interface while retaining access to DI-provided values. section 3.2.2

Listing 3.5 Function that returns a value from an injected service
import { inject } from '@angular/core';
import { AuthService } from '../../services/auth.service';

export function isAuth() {
    const authService = inject(AuthService);
    return authService.isAuth$.asObservable();
}

A small helper injects AuthService and returns a read-only authentication Observable, showing how a function can expose one service value instead of the whole service. section 3.2.2

Prefer inject when it improves the shape of the dependency boundary:

  • Inject an InjectionToken directly to infer its provided type, avoiding a separately typed constructor property and the @Inject decorator. section 3.2.3
  • Place dependencies on parent and child classes independently, avoiding constructor redeclaration and super calls solely for DI. section 3.2.3
  • Build functional guards, resolvers, and interceptors, then migrate legacy class-based forms incrementally with Angular helper support. section 3.0 section 3.6
  • Control lookup with options such as optional, self, skipSelf, and host instead of stacking constructor parameter decorators. section 3.4.1

inject does not alter Angular’s underlying DI lookup: Angular searches from the current component context through the DI tree until it finds a provider or fails. The function must therefore run in an injection context. Calling a service constructor directly with new during a unit test does not supply that context; standard TestBed-based testing does. section 3.4.1 section 3.2.4

Permission-specific functional guard

A higher-order hasPermission(permission) helper can use a closure to return a CanActivateFn for that permission. Route definitions can reuse hasPermission('CreateEmployee') or hasPermission('DeleteEmployee') instead of requiring a separate guard function for every permission. section 3.5

Adopt the function deliberately rather than mechanically. Replacing constructor injection in ordinary components may save little on its own, but function-based APIs, token injection, inheritance, and narrowly focused shared helpers benefit substantially. Legacy class-based guards, resolvers, and interceptors remain usable, allowing modernization in stages. section 3.2.2 section 3.6

How Modern Angular covers it

How deep it goes
Explains token retrieval, field injection, functional helpers, lookup options, testing constraints, and incremental migration without detailing DI internals here.
Examples
Demonstrates an employee list, authentication Observable helper, footer rendering, constants token, inheritance, and permission guard exercise.
What it assumes
Assumes familiarity with Angular dependency injection and classes while briefly contrasting constructor-based and functional dependency access.
What you can do after
Apply it via Angular to replace constructor DI, create functional helpers, configure lookup modifiers, and migrate functional routing APIs incrementally.
How it connects
Connects dependency injection with InjectionToken, guards, resolvers, interceptors, TestBed, RxJS Observable, and component inheritance.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern Angular. The section links point to the parts of the book it draws on.