69 votes

Erreur : "Encountered undefined provider ! En général, cela signifie que vous avez des dépendances circulaires".

Voici une erreur quelque peu inutile que j'obtiens dans mon application Angular / TypeScript. En attendant que quelqu'un améliore le message d'erreur, que pouvons-nous faire à ce sujet ? Quelles sont les situations les plus susceptibles de provoquer cette erreur ?

Uncaught Error: Encountered undefined provider! Usually this means you have a circular dependencies (might be caused by using 'barrel' index.ts files.
    at Object.syntaxError 
    at eval     at Array.forEach (native) [<root>]
    at CompileMetadataResolver._getProvidersMetadata 
    at CompileMetadataResolver.getNgModuleMetadata 
    at CompileMetadataResolver.getNgModuleSummary 
    at eval 
...

2 votes

J'aimerais que l'erreur mentionne le fournisseur en question ! Dans une application non triviale, il y a un grand nombre de fournisseurs à identifier.

2 votes

Je ne pense pas qu'il puisse fournir le nom exact, puisque le problème même dont il se plaint est qu'il obtient simplement undefined quelque part dans ses fournisseurs, par exemple : [Foo1, Foo2, indéfini, Foo3]. Mais il pourrait donner l'index de l'entrée qui est indéfinie ou le numéro de ligne ou quelque chose comme ça. Je suis d'accord.

69voto

Ophir Bushinsky Points 546

Il est très difficile de savoir, à partir du message d'erreur, quel fournisseur est à l'origine de ce problème. La façon dont j'ai réussi à déboguer ce problème est la suivante :

  • Je suis allé dans la node_modules@angular \compiler\bundles\compiler.umd.js fichier
  • J'ai trouvé la ligne où il est écrit : "Encountered undefined provider ! Cela signifie généralement que vous avez des dépendances circulaires. Cela peut être causé par l'utilisation de fichiers index.ts 'barils'."
  • Une ligne avant que j'ajoute console.log('type', type); afin de voir dans quel fichier se trouve le fournisseur non défini (vous pouvez également y consigner d'autres variables pertinentes).
  • Dans le fichier en question, j'ai trouvé l'importation "barrel" qui causait le problème, et je l'ai remplacée par l'importation du chemin de fichier exact.

1 votes

Tout en étant "digne d'un homme des cavernes" (l'outil pourrait sûrement sortir quelque chose si nous pouvons nous-mêmes faire cette simple modification pour obtenir un certain contexte), cette suggestion nous permet au moins d'obtenir quelques informations sur le coupable.

4 votes

J'ai ajouté une console.log( looking for ${provider}, ${debugInfo} ) ; Le fournisseur peut être indéfini, mais le debugInfo donne le contexte de l'échec.

0 votes

J'ai eu cette erreur, et il s'est avéré que c'était un problème avec un fichier baril. Une fois que j'ai arrêté d'importer le fichier de tonneau et d'utiliser ses exportations et que j'ai commencé à importer ces choses directement, ça a marché. Cela m'a pris deux jours. La mise à jour de 5 => 6 est un travail considérable.

22voto

Alexander Taylor Points 821

Une possibilité est d'essayer de déclarer un service et un module dans le même fichier, et de déclarer le module avant le service :

import {Injectable, NgModule} from '@angular/core';

@NgModule({providers: [FooService]}) // WRONG: used before declared
export class FooModule {
}

@Injectable()
export class FooService {
}

Vous pouvez résoudre ce problème en déclarant d'abord le service, ou vous pouvez utiliser la fonction forwardRef comme ça :

import {forwardRef, Injectable, NgModule} from '@angular/core';

@NgModule({providers: [forwardRef(() => FooService)]})
export class FooModule {
}

@Injectable()
export class FooService {
}

0 votes

Fonctionne parfaitement ! Existe-t-il un scénario dans lequel la création d'un forwardRef comme celui-ci serait une mauvaise idée ?

1 votes

Je ne pense pas que forwardRef soit jamais dangereux, juste inutile si vos symboles sont déclarés avant d'être utilisés. Parfois, il est préférable de mettre les choses dans des fichiers séparés, mais les déclarations de modules petits ou triviaux ne valent pas toujours le fichier supplémentaire.

0 votes

Mes composants se trouvent dans des fichiers séparés. Suffit-il de déclarer le module fournisseur en premier, ou doit-il être initialisé sur la page avant l'autre module ?

5voto

Zachary Hale Points 36

J'ai rencontré ce problème en utilisant ng-packagr pour empaqueter une bibliothèque et l'importer dans une autre bibliothèque. Ce qui s'est avéré être mon problème, c'est en effet l'importation de l'index.ts "en tonneau".

C'était en train de le briser.

import { Activate, Another, Data } from './services
@NgModule({ providers: [ Activate, Another, Data ]})

dans le dossier des services, j'avais un fichier index.ts qui exportait tous les services.

C'est réparé :

import { Activate } from './services/activate.service.ts'
import { Another} from './services/another.service.ts'
import { Data } from './services/data.service.ts'
@NgModule({ providers: [ Activate, Another, Data ]})

2voto

MalGaniS Points 312

J'ai eu cette erreur en exécutant --prod.

On ne peut pas importer ce genre de choses :

import { MyService } from '.';

Vous devez utiliser le chemin complet

import { MyService } from './my.service'

1voto

Ramesh Pareek Points 698

Vérifiez si le module peut trouver le service que vous avez mentionné.

Dans mon cas, j'exportais un guard de mon guards Ce dossier contenait un fichier index.ts. Il y avait deux autres fichiers dans ce dossier guards dossier auth.guard.ts et company.guard.ts . Idéalement, je aurait dû exporter ces fichiers dans l'index comme suit :

le contenu de gardes/index.ts

export * from './auth.guard';
export * from './company.guard'; // forgot this 

Mais j'ai oublié d'inclure la ligne ci-dessus qui exporte à partir de company.guard.ts . Cela créait un problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X