web-dev-qa-db-ja.com

Angular DIエラー - 例外:すべてのパラメータを解決できない

Angularで基本的なアプリを作成しましたが、コンポーネントの1つにサービスを挿入できないという奇妙な問題が発生しました。それは私が作成した3つの他のコンポーネントのどれにでもうまく注入します。

まず第一に、これはサービスです:

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;
  }

}

そしてそれが動作することを拒否しているコンポーネント:

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);
  }

}

ブラウザのコンソールに表示されるエラーはこれです。

例外:HeaderComponentのすべてのパラメータを解決できません:(?)。

それはプロバイダを持っているので、私はブートストラップ機能でサービスを持っています。そして、私は他のコンポーネントのコンストラクタに問題なくそれを挿入できるようです。

318
Keith Otto

バレルの代わりに直接宣言されているファイルからインポートします。

何が正確に問題を引き起こしているのかはわかりませんが、何度か言及されているのを見ました(おそらくある種の循環依存)。

それはまたバレルの輸出の順序を変えることによって修理可能であるべきです(細部を知らないが、同様に述べられました)

376

与えられた前の答えに加えて、それはあなたの注射可能なサービスが実際の@Injectable()デコレータを欠いているときにもこのエラーが投げられるようです。そのため、循環依存関係とインポート/エクスポートの順序をデバッグする前に、サービスに実際に@Injectable()が定義されているかどうかを簡単に確認してください。

これは現在のAngular最新、Angular 2.1.0に適用されます。

私はこの件に関して問題をオープンしました

268
J.P. ten Berge

Angular 2.2.3の時点で、まだ定義されていないプロバイダを注入することを可能にするforwardRef()ユーティリティ関数があります。

定義されていないということは、依存性注入マップが識別子を知らないということです。これが循環依存の間に起こることです。 Angularに依存関係を循環させることができますが、それらを解くのは非常に困難です。

export class HeaderComponent {
  mobileNav: boolean = false;

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

}

元の質問のソースコードでコンストラクタのパラメータに@Inject(forwardRef(() => MobileService))を追加することで問題は解決します。

参考文献

Angular 2 Manual:ForwardRef

Angular 2の前方参照

93
cgTag

間違った#1: /忘れたデコレータ:

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

間違った#2: / "@"記号を省略:

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

間違った#3: / "()"記号を省略

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

間違った#4: /小文字の "i":

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

間違った#5: /忘れました: '@ angular/core'から{Injectable}をインポートしてください。

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

正しい:

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

すでに述べたように、この問題は循環依存によって引き起こされるバレル内のエクスポート順序によって引き起こされます。

より詳細な説明はここにあります: https://stackoverflow.com/a/37907696/893630

24
Michael

私はまた、サービスAをサービスBに、またはその逆に注入することによってこれに遭遇しました。

おそらく避けなければならないのでこれが速く失敗するのは良いことだと思います 。サービスをよりモジュール化したり再利用したりしたい場合は、循環参照をできるだけ避けることが最善です。この ポスト はそれを取り巻く落とし穴を強調しています。 

したがって、私は以下の推奨事項があります。

  • クラスがあまりにも頻繁にやり取りしていると感じる場合( 機能の羨望 について話しています)、 2つのサービスを1つのクラス にマージすることを検討します。
  • 上記の方法でうまくいかない場合は、メッセージ交換のために両方のサービスがインジェクトでき​​る 3rd service 、(EventService)の使用を検討してください。
17
Stephen Paul

検索者のために私はこのエラーを受けました。それは単に足りない@記号でした。

すなわちこれによりCan't resolve all parameters for MyHttpServiceエラーが発生します。

Injectable()
export class MyHttpService{
}

足りない@シンボルを追加することでそれを修正します。

@Injectable()
export class MyHttpService{
}
17
HockeyJ

私の場合は、import "core-js/es7/reflect";を機能させるために@Injectableをアプリケーションに追加する必要がありました。

8
AJ Richardson

Service Bstaticプロパティ/ methodに依存するservice Aがあり、service B自体がserviceに依存する場合、このエラーが発生します依存性注入によるA。プロパティ/メソッドが静的であるというわけではありませんが、それは一種の循環依存です。おそらくAOTと組み合わせて発生するバグです。

8
M K

不足している@Injectable()デコレータに加えて

抽象クラスに@Injectable()デコレータがないと、serviceのすべてのパラメータを解決できません:(?)デコレータは、派生クラスMyServiceだけでなくBaseServiceにも存在する必要があります。

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

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

私の場合は、コンストラクタパラメータの型を宣言していないために起こりました。

私はこのようなものがありました:

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

そしてそれを以下のコードに変更することで私の問題は解決しました。

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

注入可能なconstructor()メソッドからパラメータを削除することで、私の場合は解決しました。

5
Matjaz Hirsman

私にとっては、@ Injectableの中に()がないのです。正しいのは@Injectable()です

5
repo

私の場合それはプラグインAuguryのためでした、それを無効にすることはうまくいきます。代替オプションはAOTです、また動作します。

@ Boboss74へのすべてのクレジット、彼はここに答えを投稿しました: https://github.com/angular/angular/issues/23958

4
Tinh Dang

私にとっては、誤って無効にされたpolyfills.tsファイルにこのインポートが含まれている場合は、このエラーが発生します。このエラーを回避するには、インポートされたことを確認する必要があります。

/** 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

私にとって問題はさらに厄介なことでした。サービス内でサービスを使用していて、appModuleに依存関係として追加するのを忘れていました。また起きなさい

2
Ophir Stern

@Componentデコレータか、コンポーネントが宣言されているモジュールに、プロバイダ配列を追加する必要があります。内部コンポーネントは以下のようにすることができます:

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

私の場合、コンストラクタに誤ったパラメータを渡すとこのエラーが発生します。このエラーに関する基本的な考え方は、あなたが知らないうちに関数に間違った引数を渡したことです。

export class ProductComponent {
    productList: Array<Product>;

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

私はその議論を削除することでこれを解決しました。

2
Codiee

もう1つの可能性は、tsconfig.jsonでemitDecoratorMetadataをtrueに設定していないことです。

{
  "compilerOptions": {

     ...

    "emitDecoratorMetadata": true,

     ...

    }

}
2
Stewart_R

順序付け バレル内からエクスポートされたクラスの言及はあったかもしれませんが、次のシナリオでも同じ効果が得られます。

ABCに依存している同じファイル内からクラスAB、およびCがエクスポートされているとします。

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

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

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

dependent クラス(つまりこの場合はクラスBC)はまだAngularに認識されていないので( おそらくAngularのクラスAへの依存性注入プロセスの実行時)、エラーが発生します。 

溶液

解決策は、DIが行われるクラスの前に従属クラスを宣言してエクスポートすることです。 

つまり、上記の場合、クラスAはその依存関係が定義された直後に宣言されます。 

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

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

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

サービスの名前、つまりコンストラクタ(private myService:MyService )を誤って入力すると、このエラーが発生しました。

スペルミスのサービスについては、Chrome-> Consoleでページを調べることで、どのサービスが問題だったのか(私はいくつかコンストラクタにリストされていた)判断することができました。オブジェクトObject、オブジェクトObject、?を表示すると、メッセージの一部として「パラメータ」配列リストが表示されます。 (またはそのようなもの)。 「?」のところに注意してくださいそれが問題の原因となっているサービスの位置です。 

1
maleman

サービスがコンポーネントと同じファイル(それを消費する)で定義され、サービスがafterファイルのコンポーネントで定義されている場合、これを取得できますエラー。これは、他の人が言及した同じ「forwardRef」の問題によるものです。現時点では、VSCodeはこのエラーを表示するのには向いておらず、ビルドは正常にコンパイルされます。

--aotを指定してビルドを実行すると、コンパイラの動作(おそらくツリーの揺れに関連する)が原因で、この問題を隠すことができます。

解決策:サービスが別のファイルで定義されているか、コンポーネント定義の前に定義されていることを確認してください。 (この場合、forwardRefを使用できるかどうかはわかりませんが、そうするのは面倒です)。

コンポーネント(ビューモデルのようなもの)に強く結び付けられた非常に単純なサービスがある場合-たとえばImageCarouselComponent、名前をImageCarouselComponent.service.tsにすると、すべてが他のサービスと混同されないようにできます。

1
Simon_Weaver

私の場合、その理由は次のとおりです。

  • 私の注射可能なサービスAは別のクラスBを拡張しました
  • Bは引数を必要とするコンストラクタを持っていました
  • Aではコンストラクタを定義していません

結果として、オブジェクトAを作成しようとすると、デフォルトのコンストラクタは失敗しました。なぜこれがコンパイルエラーではなかったのかわかりません。

Aにコンストラクタを追加するだけで修正できました。これはBのコンストラクタと呼ばれていました。

1

私の場合は "format(date: Date, displayFormat: Object)"メソッドをオーバーライドするために "NativeDateAdapter"を拡張しようとしていました。 

AngularMaterial-2ではDatePickerです。

だから基本的に私は@Injectableアノテーションを追加するのを忘れました。

これを私の "CustomDateAdapter"クラスに追加した後:

@Injectable({
  providedIn: 'root'
})

エラーが発生しました。

1

バレルインポートを使用する場合 - 経験則として、まず注射剤をインポートすることを検討してください。

0
marekozw

この答え この問題に非常に役立つかもしれません。さらに、私の場合は、サービスをdefaultとしてエクスポートすることが原因でした。

間違っています:

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

正しい:

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

App.module.jsでAngularの作り付けモジュール(HttpClientModule、HttpErrorResponseなど)を宣言したときに時々これが起こります。私も同じ問題に直面しましたが、今は解決しました。

私がした間違いは、Angular ModuleのImportではなくProvidersへのHttpClientModuleの言及でした。

0
ishu

ガッチャ!

上記の答えのどれもがあなたを助けなかったなら、多分あなたはコンポーネントがサービスを注入している同じ file からある要素をインポートしています。

私はもっ​​とよく説明します:

これはサービス file :です。

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

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

これがコンポーネント file です。

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

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

そのため、シンボルが同じコンポーネント内ではなく、同じファイル内にあっても問題が発生します。シンボル(関数、定数、クラスなど)を別の場所に移動すると、エラーは消えます。

0

私にとっては、@ComponentデコレータとComponentクラスの間に空の行があるためです。これにより、デコレータはクラスに適用されませんでした。

0
fwip

エラーのフィードバックが不足しているため、これはデバッグが非常に難しい問題になる可能性があります。実際の循環依存関係を心配している場合は、スタックトレースで調べることが最も重要です。a)サービスの名前b)疑問符のあるそのサービスのコンストラクタパラメータ。このように見えるなら:

authServiceのすべてのパラメータを解決することはできません。([object Object]、[object Object]、[object Object]、[object Object]、?)

それから5番目のパラメータはAuthServiceにも依存するサービスであることを意味します。つまり疑問符は、DIによって解決されなかったことを意味します。

そこから、コードを再構築して2つのサービスを分離するだけです。

0
sarora

私の場合は、同じコンポーネントファイルからClassとEnumをエクスポートしていました。

mComponent.component.ts

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

それから、私はMyEnumの子からMyComponentClassを使用しようとしていました。 すべてのパラメータを解決できないというエラーが発生していました

MyEnumMyComponentClassとは別のフォルダーに移動することで、問題は解決しました。

GünterZöchbauerが述べたように、これはサービスまたはコンポーネントが循環的に依存しているために起こっています。

interfaceも参照するときに起こります。

interfaceclassに変更すると、@Injectの有無にかかわらず動作して修正されました。

0
zurfyx

私の場合は循環参照でした。 MyServiceからMyservice2 を呼び出し、MyService2からMyServiceを呼び出しました。

良くない :(

0
lucbonnin

私にとってこれは、コンパイル時間を早くするために-aotフラグの使用を止めたためです。

 ng serve -aot
0
B Jarmain

私の場合は、依存関係のないサービスに依存関係を持っていたので、サービスクラスにconstructor()関数を追加しませんでした。私はパラメータなしのコンストラクタを依存サービスクラスに追加しました、そしてすべてが働き始めました。

0
Hallmanac