Encyclopédie des erreurs

L'injector a déjà été détruit

Cette erreur survient lorsque vous tentez de récupérer un service depuis un injector qui a déjà été détruit. Cela arrive généralement lorsque du code tente d'accéder à des dépendances après la destruction d'un composant, d'une directive ou d'un module.

Scénarios courants

Accéder à des services dans des callbacks après la destruction

Lorsqu'un composant est détruit, son injector l'est aussi. Si un callback asynchrone tente ensuite d'accéder à des services, cette erreur survient :

@Component(/* ... */)
export class UserProfile implements OnInit {
  private userClient = inject(UserClient);

  ngOnInit() {
    setTimeout(() => {
      // ERROR: If component was destroyed before timeout fires,
      // the injector is no longer available
      this.userClient.fetchData();
    }, 5000);
  }
}

Accéder à des services après le désabonnement

Des problèmes similaires surviennent avec les observables si le nettoyage se fait dans le mauvais ordre :

@Component(/* ... */)
export class DataView implements OnDestroy {
  private dataStore = inject(DataStore);

  ngOnDestroy() {
    // Problematic: attempting to use the injector during destruction
    // after other cleanup may have occurred
    this.dataStore.cleanup();
  }
}

Déboguer l'erreur

Pour corriger cette erreur :

  1. Vérifiez les opérations asynchrones — Assurez-vous que les callbacks, les promises et les abonnements sont annulés lorsque le composant est détruit. Utilisez takeUntilDestroyed() ou DestroyRef pour le nettoyage.

  2. Capturez les dépendances tôt — Stockez les références aux services dans des champs de classe plutôt que d'accéder à l'injector dans des callbacks.

  3. Protégez-vous contre l'état détruit — Pour les opérations susceptibles de survivre au composant, vérifiez que le composant est toujours actif avant d'accéder à des services.

@Component(/* ... */)
export class UserProfile implements OnInit {
  private destroyRef = inject(DestroyRef);
  private userClient = inject(UserClient);

  ngOnInit() {
    // Use takeUntilDestroyed to automatically cancel when destroyed
    interval(5000)
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe(() => {
        this.userClient.fetchData();
      });
  }
}

La stack trace indique où l'injector détruit a été sollicité. Remontez-la pour identifier l'opération asynchrone qui a survécu à son composant.