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


431

Angular 2で基本的なアプリを作成しましたが、コンポーネントの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:(?)のすべてのパラメーターを解決できません。

ブートストラップ機能にサービスがあるので、プロバイダーがあります。そして、他のコンポーネントのコンストラクタに問題なく注入できるようです。


14
多分インポート?である(バレル)?代わりに、それが直接宣言されているファイルからインポートしようとすることはできますか?'../'index.ts
ギュンターZöchbauer

奇跡的にそれは修正したようです!私がサービスをテストした他のコンポーネントがそうであったとき、それはバレルを使用して機能しないことを奇妙に思います。コメントではなく回答として投稿したい場合は、受け付けます。
キースOtto

11
通常、循環依存関係です。
ゲイリー

この問題は循環依存でも発生しました。Webパックの新しいバージョンは、これを伝えるのがはるかに優れていることに注目する価値があります
Enn

循環依存のように見えます。angular> = 4を使用すると、intex.ts(バレル)を削除して、必要なものをすべて直接インポートできます。
ラムガロット

回答:


457

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

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

また、バレル内のエクスポートの順序を変更することで修正できるはずです(詳細は不明ですが、言及されていました)。


16
これは、たとえば、最初のサービスがバレルの最初に来る必要がある別のサービスに注入されたサービスがある場合に正しいです。
Joao Garin

17
Angular2チームは、このような問題が多いため、もはや樽を推奨していません。私は:)助けることができる聞いて喜ん
ギュンターZöchbauer

13
Angular 2チームがバレルを推奨しないことを知りませんでした。もしそうなら、彼らは彼らの利点を議論する用語集でそれを注意する必要があります。そしてangular2-webpack-starterのようなプロジェクトはそれらを使用すべきではありません。
ブルー

3
これは修正されました(の問題ではありません2.0.2)。特に、異なるモジュール間で複数のモデルとサービスをインポートする必要がある場合、バレルはまだ便利です。これimport { cleanValues, getState, FirebaseService, NotificationService, ... } from '../../shared/services';が機能しなかったときの痛みでした(; NgModuleシングルトンサービスでは役に立ちません...
Sasxa

3
Argghhバレル(index.ts)ファイルのエクスポートの順序を変更することで解決しました。ありがとうございました
Spock

331

上記の回答に加えて、注入可能なサービスに実際の@Injectable()デコレーターが欠落している場合にも、このエラーがスローされるようです。したがって、循環依存関係とインポート/エクスポートの順序をデバッグする前に、サービスが実際に@Injectable()定義されているかどうかを簡単に確認してください。

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

この件について問題を提起しました


ええ、このエラーは通常、Router@ Injectableを追加するのを忘れているためです。たとえば、「@ angular / router」からをインポートしているだけで、そのインジェクタブルがない場合、このエラーは常に発生します(1行にするとすぐに挿入されたルーターを使用するコード
Eric Bishard 2017年

すばらしい回答です。私の問題は、サービスにメソッドを追加し、最後のブレースの後にセミコロンを追加しなかったことです。なぜこのようにする必要があるのか​​はわかりませんが、コンポーネントクラスには当てはまりません...とりあえず先に進んでください!
egimaben

このエラーが発生する単純なモデルがありました。モデルのコンストラクターでプロパティを作成するショートカットを使用しました。プロパティのタイプは文字列と整数のみでした。その後、突然この問題が発生し始めました。@Injectable()を追加して問題を修正しました。私の他のどのモデルにもInjectableが追加されていないので奇妙です。この新しいモデルを追加する前に、かなりの数のライブラリをアップグレードしたことを追加する必要があります。おそらくそれと関係があるかもしれませんが、今は働いています。ありがとう。
Moutono 2018年

@Moutono正解。サービスに空のコンストラクターがある場合、依存関係の注入はトリガーされたようには見え@injectable()ないため、必要ありません。それ自体が別の奇妙なことです。ただし、何かを注入することを決定する必要があるときのために、私はまだそれを追加します。
JP ten Berge

サービスに@Injectable()で装飾する必要がある基本クラスがある場合
Sam Shilesに注意してください

110

角度のとおり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マニュアル:ForwardRef

Angular 2の前方参照


3
forwardRef()すでにアルファ版でした;-) Mobile同じファイルでさらにサービスが宣言されている場合にのみ必要です。クラスは別のファイルにある場合は、する必要はありませんforwardRef()
ギュンター・Zöchbauer

4
GünterZöchbauer、私はまだ自分のコードの実際の問題を理解しようとしていますが、その間forwardRef()Can't resolve all parameters for ...メッセージを取り除くのに役立ちました。問題に対するより良い解決策を探している間、少なくともコンポーネントは機能しています。(そして、はい、失敗した依存関係はそのファイルから直接インポートされます)
Nik

4
@GünterZöchbauer私は参照で私の答えを更新しました。私はあなたの答えを奪うつもりはありませんが、これは実際に問題を解決し、人々はそれについて知る必要があります。あなたが質問をグーグルするならば、使うと言う結果はありませんforwardRef。見つけるのはとても難しいです。この問題を解決するために昨日一日中私にかかりました。
Reactgular 16

変だ。私はforeardRef自分自身の使用を提案する少なくとも12の回答を投稿しましたNgModuleが、紹介された後はもうありません。私は担当者を失うことを心配していません。数か月間、これがポップアップしなくなった後、なぜこれに遭遇したのか興味があります。数日後に家に帰ったら、よく見ていきます。フィードバックをどうもありがとう。
ギュンターZöchbauer

2
誰かがインポートについても迷子になった場合:import {Component、Inject、ForwardRefFn、forwardRef} from '@ angular / core';
ナタナエル2017年

69

間違い#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 { ... }


21

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

とにかく避けるべきだと思うので、これがすぐに失敗するのは良いことだと思います。サービスをよりモジュール化して再利用できるようにしたい場合は、循環参照をできるだけ避けることをお勧めします。この投稿は、それを取り巻く落とし穴を強調しています。

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

  • クラスが頻繁に相互作用していると感じる場合(私は機能羨望について話しています)、2つのサービスを1つのクラスにマージすることを検討することをお勧めします
  • 上記の方法でうまくいかない場合は、3番目のサービスEventService)を使用することを検討してください。このサービスは、メッセージを交換するために両方のサービスから挿入できます。

1
これは間違いなく私に起こったことであり、これが進むべき道です。更新が必要なサービスが複数あることがわかっている場合は、EventServiceを使用します。これらのイベントに基づいてアプリケーションを拡張するときに、これらのイベントを利用する必要があるので、より拡張性があります。
themightybun 2017年

17

サーチャーのために; このエラーが発生しました。それは単に欠けていた@記号でした。

すなわち、これはCan't resolve all parameters for MyHttpServiceエラーを生成します。

Injectable()
export class MyHttpService{
}

不足している@シンボルを追加すると修正されます。

@Injectable()
export class MyHttpService{
}

2
私の場合、@ Injectableとサービスクラス定義の間に追加のクラスとインターフェースを追加したため、サービスクラスは注入可能としてマークされなくなりました。
ハーク

他の注入可能なサービスを使用するサービスクラスで@Injectable()デコレータを完全に忘れた場合、不適切に装飾されたサービスもこのエラーをスローします。
I. Buchan 2017年

10

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


9

別の可能性はemitDecoratorMetadata、tsconfig.jsonでtrueに設定していないことです

{
  "compilerOptions": {

     ...

    "emitDecoratorMetadata": true,

     ...

    }

}

8

あなたは、サービス持っている場合は、このエラーを取得するAに依存静的プロパティ/メソッドサービスのB及びサービスB自体がサービスに依存してAトラフ依存性注入を。つまり、プロパティ/メソッドが静的であるためではありませんが、循環依存の一種です。おそらくAOTと組み合わせて発生するバグです。


同じファイルで単純に定義された関数への依存関係がある場合にも、私はそれを経験しました。別のファイルに分割することで修正されました。
Joe

1
言及していただきありがとうございます。私は正確な状況に自分自身を見つけました。静的クラスに直接アクセスすることがDIと関係があることに気づきませんでした。私はこのスキームを持っていました:A -> B両方とも同じ静的クラスを使用していました。解決策はforwardRef助けになりますが、これがどのように解決できるかを見ていきます。私はおそらく、この静的クラスから実際のサービスを作成しようとするでしょう(これは、より良い設計にもつながります)。
Slava Fomin II 2017

8

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

@Injectable()抽象クラスのデコレーターが欠落しているため、サービスのすべてのパラメーターを解決できません:(?)デコレーターMyServiceは、派生クラスと同様に存在する必要がありますBaseService

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

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

7

私の場合は、コンストラクタパラメータの型を宣言しなかったために発生しました。

私はこのようなものを持っていました:

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

それを以下のコードに変更すると、問題が解決しました。

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

5

私にとっては()、@ Injectableの欠如でした。適切なのは@Injectable()です


または、私の場合、誤って@を削除します
TDP 2018

4

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


これもまさに私の問題でした。私はそれを投稿するようになりましたが、あなたが最初に投稿したことを発見しました!+1
aesede

次に、パラメータを再利用可能なサービスに送信する方法は?
3gwebtrain


2

私にとっては、問題はさらに煩わしく、サービス内でサービスを使用していて、appModuleに依存関係として追加するのを忘れていました!これが誰かがアプリを分解するために数時間節約するのに役立ち、再びそれを再構築することを願っています


1
@Injectアノテーションがありませんでした。エラーメッセージが少し言っていることを正確に見落としていた。循環依存関係が疑われない場合は、エラーで言及されたクラスに移動し、すべてのコンストラクターパラメーターと注釈が付けられたクラスメンバー@Injectを調べて、それらすべてに対してDIが正しく行われていることを確認してください。DIの詳細はこちら:angular.io/docs/ts/latest/guide/dependency-injection.html
Alexander Taylor

2

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

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

2

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

export class ProductComponent {
    productList: Array<Product>;

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

私はその引数を削除するだけでこれを解決しました。


2

私にとって、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

私の場合、「NativeDateAdapter」を拡張するために「」を拡張しようとしていましたformat(date: Date, displayFormat: Object)」メソッド。

AngularMaterial-2のDatePickerで。

だから基本的に私は追加するのを忘れた @Injectable注釈。

これを「CustomDateAdapter」クラスに追加した後:

@Injectable({
  providedIn: 'root'
})

エラーが発生しました。


これでうまくいきましたが、理由はわかりません。DIを機能させるために、サービスと、DIを介してそれを受け取るコンポーネントの両方を提供する必要がありますか?
Mike Furlender

2

この回答は、この問題に非常に役立つ場合があります。さらに、私の場合、サービスをdefaultすることが原因でした。

違う:

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

正しい:

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

2

エラーのフィードバックがないため、これはデバッグするのが本当に難しい問題です。実際の循環依存関係が心配な場合は、スタックトレースで確認する最も重要なことをここに示します。

AuthServiceのすべてのパラメーターを解決できません:([オブジェクトオブジェクト]、[オブジェクトオブジェクト]、[オブジェクトオブジェクト]、[オブジェクトオブジェクト] 、?)

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

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


1

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

スペルミスのあるサービスについては、Chrome-> Consoleでページを検査することにより、どのサービスが問題であるか(コンストラクターにいくつかリストしました)を特定できました。メッセージの一部として、object Object、object Object 、? (またはそのようなもの)。「?」それが問題の原因となっているサービスの位置です。


1

が、順序バレル内からエクスポートされたクラスが言及されている場合がありますが、次のシナリオでも同じ効果が得られる場合があります。

あなたはクラスを持っていると仮定しABC同じファイル内から輸出さAに依存BしてC

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

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

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

以来依存クラス(つまり、この場合には、クラスBとはC)まだ(角度に知られていない、おそらく実行時にクラスの角度の依存性注入処理中にAエラーが発生します)。

解決

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

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

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

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

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

1

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

mComponent.component.ts

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

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

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

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


1

サービスが(それを消費する)コンポーネントと同じファイルで定義され、サービスが後に定義されている場合ファイル内のコンポーネントのにいる場合、このエラーが発生する可能性があります。これは、他の人が言及した同じ「forwardRef」問題が原因です。現時点では、VSCodeはこのエラーを表示することについて優れておらず、ビルドは正常にコンパイルされます。

でビルドを実行すると--aot、コンパイラの動作方法(おそらくツリーの揺れに関連する)が原因でこの問題がマスクされる可能性があります。

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

コンポーネントに非常に強く結びついた非常にシンプルなサービスがある場合(ビューモデルのようなもの)-例 ImageCarouselComponentImageCarouselComponent.service.ts他のサービスと混同されないように名前を付けます。


1

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

良くない :(


1

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

  • 私の注射サービスAは別のクラスBを拡張しました
  • Bには、引数を必要とするコンストラクターがありました
  • 私はAでコンストラクタを定義していませんでした

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

私は、Aにコンストラクターを追加するだけで修正しました。これは、Bのコンストラクターを正しく呼び出したものです。


1

ゲッチャ!

上記の回答のいずれも役に立たなかった場合は、コンポーネントがサービスを注入している同じファイルからいくつかの要素をインポートしている可能性があります。

私はよりよく説明します:

これはサービスファイルです

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

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

これはコンポーネントファイルです

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

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

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


1

Angular 6以降のバージョンの場合は、

@Injectable({
  providedIn: 'root'
})

..サービスクラスの真上に他の行がない

利点

  • モジュールにサービスを追加する必要はありません(「自動検出」されます)
  • サービスはシングルトンになります(ルートに注入されるため)

[ 角度付きドキュメント ]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.