webentwicklung-frage-antwort-db.com.de

Angular DI Error - EXCEPTION: Alle Parameter können nicht aufgelöst werden

Ich habe eine grundlegende App in Angular erstellt, aber ich bin auf ein seltsames Problem gestoßen, bei dem ich keinen Dienst in eine meiner Komponenten einschleusen kann. Es injiziert fein in alle drei anderen Komponenten, die ich erstellt habe.

Für den Anfang ist dies der Service:

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

@Injectable()
export class MobileService {
  screenWidth: number;
  screenHeight: number;

  constructor() {
    this.screenWidth = window.outerWidth;
    this.screenHeight = window.outerHeight;

    window.addEventListener("resize", this.onWindowResize.bind(this) )
  }

  onWindowResize(ev: Event) {
    var win = (ev.currentTarget as Window);
    this.screenWidth = win.outerWidth;
    this.screenHeight = win.outerHeight;
  }

}

Und die Komponente, mit der sie nicht arbeiten möchte:

import { Component, } from '@angular/core';
import { NgClass } from '@angular/common';
import { ROUTER_DIRECTIVES } from '@angular/router';

import {MobileService} from '../';

@Component({
  moduleId: module.id,
  selector: 'pm-header',
  templateUrl: 'header.component.html',
  styleUrls: ['header.component.css'],
  directives: [ROUTER_DIRECTIVES, NgClass],
})
export class HeaderComponent {
  mobileNav: boolean = false;

  constructor(public ms: MobileService) {
    console.log(ms);
  }

}

Der Fehler, den ich in der Browserkonsole bekomme, lautet:

AUSNAHME: Alle Parameter für HeaderComponent: (?) Können nicht aufgelöst werden.

Ich habe den Dienst in der Bootstrap-Funktion, also hat es einen Provider. Und ich scheine es in der Lage zu haben, sie ohne Probleme in den Konstruktor meiner anderen Komponenten einzufügen.

318
Keith Otto

Importieren Sie es aus der Datei, in der es direkt anstelle des Fasses deklariert wird.

Ich weiß nicht, was genau das Problem verursacht, aber ich habe mehrere Male erwähnt (wahrscheinlich eine Art zirkuläre Abhängigkeit).

Es sollte auch fixierbar sein, indem die Reihenfolge der Exporte im Fass geändert wird (Sie kennen keine Details, wurden aber auch erwähnt)

376

Neben den vorherigen Antworten scheint es, dass dieser Fehler auch ausgelöst wird, wenn bei Ihrem injizierbaren Dienst der eigentliche @Injectable()-Dekorateur fehlt. Bevor Sie also die zyklische Abhängigkeit und die Reihenfolge Ihrer Importe/Exporte debuggen, prüfen Sie einfach, ob in Ihrem Dienst tatsächlich @Injectable() definiert ist.

Dies gilt für die aktuelle Version von Angular, Angular 2.1.0.

Ich habe eine Ausgabe zu diesem Thema aufgeschlagen .

268
J.P. ten Berge

Ab Angular 2.2.3 gibt es jetzt eine forwardRef()-Utility-Funktion, mit der Sie noch nicht definierte Anbieter einspeisen können.

Mit nicht definiert meine ich, dass die Abhängigkeitsinjektionskarte den Bezeichner nicht kennt. Dies geschieht während zirkularer Abhängigkeiten. In Angular können Sie kreisförmige Abhängigkeiten haben, die nur schwer zu entwirren und zu sehen sind.

export class HeaderComponent {
  mobileNav: boolean = false;

  constructor(@Inject(forwardRef(() => MobileService)) public ms: MobileService) {
    console.log(ms);
  }

}

Durch Hinzufügen von @Inject(forwardRef(() => MobileService)) zu dem Parameter des Konstruktors im Quellcode der ursprünglichen Frage wird das Problem behoben.

Verweise

Angular 2 Manual: ForwardRef

Weiterleiten von Referenzen in Winkel 2

93
cgTag

FALSCH # 1: Dekorateur vergessen:

//Uncaught Error: Can't resolve all parameters for MyFooService: (?).
export class MyFooService { ... }

FALSCH # 2: Auslassen des "@" -Symbols:

//Uncaught Error: Can't resolve all parameters for MyFooService: (?).
Injectable()
export class MyFooService { ... }

FALSCH # 3: Auslassen von Symbolen "()":

//Uncaught Error: Can't resolve all parameters for TypeDecorator: (?).
@Injectable
export class MyFooService { ... }

FALSCH 4: Kleinbuchstabe "i":

//Uncaught ReferenceError: injectable is not defined
@injectable
export class MyFooService { ... }

FALSCH # 5: Sie haben vergessen: Import {Injectable} von '@ angle/core';

//Uncaught ReferenceError: Injectable is not defined
@Injectable
export class MyFooService { ... }

RICHTIG:

@Injectable()
export class MyFooService { ... }
46
J.M.I. MADISON

Wie bereits erwähnt, wird das Problem durch die Exportreihenfolge innerhalb des Fasses verursacht, die durch zirkuläre Abhängigkeiten verursacht wird.

Eine ausführlichere Erklärung finden Sie hier: https://stackoverflow.com/a/37907696/893630

24
Michael

Ich bin auch auf dieses Problem gestoßen, als ich Service A in Service B einspeiste und umgekehrt.

Ich finde es gut, dass dies schnell ausfällt, da es wahrscheinlich sowieso vermieden werden sollte. Wenn Sie möchten, dass Ihre Services modularer/wiederverwendbarer sind, sollten Sie Zirkularreferenzen möglichst vermeiden. Dieses post hebt die Fallstricke hervor. 

Daher habe ich folgende Empfehlungen:

  • Wenn Sie der Meinung sind, dass die Klassen zu oft miteinander interagieren (ich spreche von feature envy ), möchten Sie vielleicht die zwei Dienste in einer Klasse zusammenfassen betrachten.
  • Wenn das Obige für Sie nicht funktioniert, sollten Sie ein 3. Dienst (eine EventService) in Betracht ziehen, das beide Dienste einspeisen können, um Nachrichten auszutauschen.
17
Stephen Paul

Zum Nutzen der Suchenden; Ich habe diesen Fehler bekommen. Es war einfach ein fehlendes @ -Symbol.

Das heißt Dies erzeugt den Can't resolve all parameters for MyHttpService-Fehler.

Injectable()
export class MyHttpService{
}

Durch das Hinzufügen des fehlenden @-Symbols wird dieses Problem behoben.

@Injectable()
export class MyHttpService{
}
17
HockeyJ

In meinem Fall musste ich meiner Anwendung import "core-js/es7/reflect"; hinzufügen, damit @Injectable funktioniert.

8
AJ Richardson

Sie erhalten diesen Fehler, wenn Sie über den Dienst A verfügen, der von einer static-Eigenschaft/-Methode des Dienstes B abhängig ist und der Dienst B selbst vom Dienst abhängig ist EINE durch Abhängigkeitsinjektion. Es handelt sich also um eine Art zirkuläre Abhängigkeit, obwohl die Eigenschaft/Methode nicht statisch ist. Wahrscheinlich ein Fehler, der in Kombination mit AOT auftritt.

8
M K

Zusätzlich zum fehlenden @Injectable() Dekorateur

Fehlender @Injectable()-Dekorator in der abstrakten Klasse produzierte die folgenden Parameter: (?) Der Dekorator muss in MyService sowie in der abgeleiteten Klasse BaseService vorhanden sein

//abstract class
@Injectable()
abstract class BaseService { ... }

//MyService    
@Injectable()
export class MyService extends BaseService {
.....
}
7
Bart

In meinem Fall ist es passiert, weil ich den Typ für einen Konstruktorparameter nicht deklariert habe.

Ich hatte so etwas:

constructor(private URL, private http: Http) { }

und dann den Code zu ändern, löste mein Problem.

constructor(private URL : string, private http: Http) {}
6
Alf Moh

Das Entfernen von Parametern aus der injectable constructor () -Methode hat es für meinen Fall gelöst.

5
Matjaz Hirsman

für mich war es einfach () in @Injectable. Richtig ist @Injectable ()

5
repo

In meinem Fall war es wegen des Plugins Augury, Deaktivierung wird gut funktionieren. Alternative Option ist aot, funktioniert auch.

alle Credits an @ Boboss74, er hat die Antwort hier veröffentlicht: https://github.com/angular/angular/issues/23958

4
Tinh Dang

Ich habe diesen Fehler erhalten, als ich fälschlicherweise deaktiviert habe diesen Import in die Datei polyfills.ts. Sie müssen sicherstellen, dass er importiert wird, um diesen Fehler zu vermeiden .

/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';
2
Ahmed Elkoussy

Nun, für mich war das Problem noch ärgerlicher. Ich habe einen Dienst innerhalb eines Dienstes verwendet und habe vergessen, ihn als Abhängigkeit in appModule! Hinzuzufügen. Ich hoffe, dies hilft jemandem, der die App herunterbricht, um sie wieder aufzubauen

2
Ophir Stern

Sie müssen ein Provider-Array im @Component-Dekorator oder in dem Modul hinzufügen, in dem Ihre Komponente deklariert ist. Innerhalb der Komponente können Sie Folgendes tun:

@Component({
  moduleId: module.id,
  selector: 'pm-header',
  templateUrl: 'header.component.html',
  styleUrls: ['header.component.css'],
  directives: [ROUTER_DIRECTIVES, NgClass],
  providers: [MobileService]
})
2
Shivang Gupta

In meinem Fall führt die Übergabe falscher Parameter an den Konstruktor zu diesem Fehler. Grundlegende Idee zu diesem Fehler ist, dass Sie unwissentlich einige falsche Argumente an eine Funktion übergeben haben.

export class ProductComponent {
    productList: Array<Product>;

    constructor(productList:Product) { 
         // productList:Product this arg was causing error of unresolved parameters.
         this.productList = [];
    }
}

Ich löste dieses Problem, indem ich dieses Argument einfach entfernte.

2
Codiee

Eine andere Möglichkeit ist, emitDecoratorMetadata in tsconfig.json nicht auf true zu setzen

{
  "compilerOptions": {

     ...

    "emitDecoratorMetadata": true,

     ...

    }

}
2
Stewart_R

Obwohl das ordering von exportierten Klassen aus Fässern erwähnt wurde, kann das folgende Szenario den gleichen Effekt erzeugen.

Angenommen, Sie haben Klassen A, B und C aus derselben Datei exportiert, wobei A von B und C abhängt:

@Injectable()
export class A {
    /** dependencies injected */
    constructor(private b: B, private c: C) {}
}

@Injectable()
export class B {...}

@Injectable()
export class C {...}

Da die abhängigen Klassen (dh in diesem Fall die Klassen B und C) Angular noch nicht bekannt sind (wahrscheinlich zur Laufzeit während Angulars Abhängigkeitsinjektionsprozess von der Klasse A), ist der Fehler aufgetreten wird angehoben. 

Lösung

Die Lösung besteht darin, die abhängigen Klassen vor der Klasse, in der die DI durchgeführt wird, zu deklarieren und zu exportieren. 

in dem obigen Fall wird die Klasse A gleich nach der Definition ihrer Abhängigkeiten deklariert: 

@Injectable()
export class B {...}

@Injectable()
export class C {...}

@Injectable()
export class A {
    /** dependencies injected */
    constructor(private b: B, private c: C) {}
}

Dieser Fehler ist aufgetreten, indem der Name des Dienstes falsch eingegeben wurde, d. H. Konstruktor (private myService: MyService ).

Bei falsch geschriebenen Diensten konnte ich feststellen, welcher Dienst das Problem war (ich hatte mehrere im Konstruktor aufgeführt), indem ich die Seite in Chrome-> Console untersuchte. Sie sehen als Teil der Nachricht eine "Parameter" -Array-Liste, indem Sie Objekt Object, Object Object,? (oder sowas ähnliches). Beachten Sie, wo das "?" ist und das ist die Position des Dienstes, der das Problem verursacht. 

1
maleman

In meinem Fall war der Grund folgender:

  • mein injizierbarer Service A erweiterte eine weitere Klasse B
  • B hatte einen Konstruktor, der ein Argument erforderte
  • Ich hatte in A keinen Konstruktor definiert

Beim Versuch, ein Objekt A zu erstellen, ist der Standardkonstruktor daher fehlgeschlagen. Ich habe keine Ahnung, warum dies kein Kompilierfehler war.

Ich habe es behoben, indem ich einfach einen Konstruktor in A hinzugefügt habe, der den Konstruktor von B korrekt aufgerufen hat.

1

In meinem Fall habe ich versucht, "NativeDateAdapter" zu erweitern, um die "format(date: Date, displayFormat: Object)" -Methode zu überschreiben. 

In AngularMaterial-2 DatePicker.

Im Grunde habe ich vergessen, @Injectable anotation hinzuzufügen.

Nachdem ich dies meiner "CustomDateAdapter" -Klasse hinzugefügt habe:

@Injectable({
  providedIn: 'root'
})

Fehler ist gegangen.

1

Wenn Sie Fassimporte verwenden, sollten Sie zuerst den Import von Injektionsmitteln als Faustregel betrachten.

0
marekozw

Diese Antwort könnte für dieses Problem sehr hilfreich sein. Außerdem war für meinen Fall das Exportieren des Dienstes als default die Ursache.

FALSCH:

@Inject()
export default class MobileService { ... }

RICHTIG:

@Inject()
export class MobileService { ... }
0
otiai10

Dies geschieht manchmal, wenn Sie das eingebaute Modul von Angular (HttpClientModule, HttpErrorResponse usw.) in app.module.js deklariert haben. Ich stand auch vor demselben Problem, wurde aber jetzt gelöst.

Der Fehler, den ich gemacht habe, war, das HttpClientModule in Providers anstelle von Import of Ewnormodul zu erwähnen

0
ishu

Erwischt!

Wenn Ihnen keine der obigen Antworten geholfen hat, importieren Sie möglicherweise ein Element aus derselben Datei , in die eine Komponente den Dienst einfügt.

Ich erkläre es besser:

Dies ist der Dienst file :

// your-service-file.ts
import { helloWorld } from 'your-component-file.ts'

@Injectable()
export class CustomService() {
  helloWorld()
}

Dies ist die Komponente file :

@Component({..})
export class CustomComponent {
  constructor(service: CustomService) { }
}

export function helloWorld() {
  console.log('hello world');
}

Dies führt zu Problemen, selbst wenn sich das Symbol nicht in derselben Komponente, sondern nur in derselben Datei befindet. Bewegen Sie das Symbol (es kann eine Funktion, eine Konstante, eine Klasse usw. sein) an eine andere Stelle, und der Fehler verschwindet

0

Für mich war es, weil ich eine leere Zeile zwischen meinem @Component-Dekorateur und meiner Component-Klasse hatte. Dies führte dazu, dass der Dekorateur nicht auf die Klasse angewendet wurde.

0
fwip

Dies kann ein wirklich schwieriges Problem sein, da der Fehler keine Rückmeldung enthält. Wenn Sie über eine tatsächliche zyklische Abhängigkeit besorgt sind, sollten Sie im Stack-Trace Folgendes beachten: a) den Namen des Dienstes b) den Konstruktorparameter in diesem Dienst, der ein Fragezeichen aufweist, z. wenn es so aussieht:

können nicht alle Parameter für AuthService auflösen: ([Objekt Objekt], [Objekt Objekt], [Objekt Objekt], [Objekt Objekt],?)

dann bedeutet dies, dass der 5. Parameter ein Dienst ist, der auch von AuthService abhängt. Fragezeichen, bedeutet, dass es nicht von DI gelöst wurde.

Von dort aus müssen Sie nur noch die beiden Dienste entkoppeln, indem Sie den Code umstrukturieren.

0
sarora

In meinem Fall habe ich aus derselben Komponentendatei eine Klasse und ein Enum exportiert:

mComponent.component.ts:

export class MyComponentClass{...}
export enum MyEnum{...}

Dann versuchte ich, MyEnum von einem Kind von MyComponentClass zu verwenden. Das verursachte den Kann nicht alle Parameter auflösen .

Durch Verschieben von MyEnum in einen separaten Ordner von MyComponentClass wurde das Problem gelöst!

Wie Günter Zöchbauer erwähnt, geschieht dies, weil eine Dienstleistung oder Komponente zirkular abhängig ist.

Dies geschieht auch, wenn eine interface referenziert wird.

Durch Ändern von interface für class wurde das Problem behoben und es wurde mit und ohne @Inject gearbeitet.

0
zurfyx

Wenn Ihr Dienst in derselben Datei als eine Komponente definiert ist (die sie verbraucht) und der Dienst definiert ist nach der Komponente in der Datei, erhalten Sie möglicherweise diese Fehlermeldung. Dies ist auf das gleiche 'forwardRef'-Problem zurückzuführen, das von anderen bereits erwähnt wurde. Derzeit ist VSCode nicht besonders gut darin, diesen Fehler anzuzeigen und das Build erfolgreich zu kompilieren.

Das Ausführen des Builds mit --aot kann dieses Problem aufgrund der Funktionsweise des Compilers (möglicherweise im Zusammenhang mit Tree Shaking) maskieren. 

Lösung: Stellen Sie sicher, dass der Dienst in einer anderen Datei oder vor der Komponentendefinition definiert ist. (Ich bin nicht sicher, ob forwardRef in diesem Fall verwendet werden kann, aber es scheint unbeholfen zu sein).

Wenn ich einen sehr einfachen Dienst habe, der sehr stark an eine Komponente gebunden ist (ähnlich wie ein Ansichtsmodell) - z. ImageCarouselComponent, ich kann es ImageCarouselComponent.service.ts nennen, damit es nicht mit meinen anderen Diensten vermischt wird.

0
Simon_Weaver

In meinem Fall handelte es sich um einen Zirkelverweis . Ich hatte MyService aufgerufen, Myservice2 Und MyService2 MyService aufzurufen.

Nicht gut :(

0
lucbonnin

Für mich lag das daran, dass ich die -aot-Flag nicht mehr verwendete, während ich versuchte, die Kompilierzeit zu verkürzen.

 ng serve -aot
0
B Jarmain

In meinem Fall nahm ich eine Abhängigkeit von einem Dienst an, der keine Abhängigkeiten hatte, und fügte daher der Funktionsklasse keine Funktion constructor() hinzu. Ich fügte der abhängigen Serviceklasse einen parameterlosen Konstruktor hinzu und alles begann zu funktionieren.

0
Hallmanac