本文へスキップ
バージョン:v8

ビルドエラー

よくある間違い

デコレーターでの括弧の忘れ

デコレーターには、アノテーションの後に括弧 `()` が必要です。例としては、`@Injectable()`、`@Optional()`、`@Input()`などがあります。

@Directive({
selector: 'my-dir',
})
class MyDirective {
// Wrong, should be @Optional()
// @Optional does nothing here, so MyDirective will error if parent is undefined
constructor(@Optional parent: ParentComponent) {}
}

よくあるエラー

すべての引数を解決できません

Cannot resolve all parameters for 'YourClass'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'YourClass' is decorated with Injectable.

この例外は、Angularが`YourClass`のコンストラクターの1つ以上の引数について混乱していることを意味します。依存性注入を行うために、Angularは注入する引数の型を知る必要があります。引数のクラスを指定することで、Angularにこれを知らせます。以下のことを確認してください。

  • 引数のクラスをインポートしている。
  • 引数を適切にアノテーションするか、型を指定している。
import { MyService } from 'my-service'; // Don't forget to import me!

@Component({
template: `Hello World`,
})
export class MyClass {
// service is of type MyService
constructor(service: MyService) {}
}

場合によっては、コード内の循環参照が原因でこのエラーが発生することがあります。循環参照とは、2つのオブジェクトがお互いに依存しており、互いの前にどちらを宣言することもできない状態です。これを回避するために、Angularに組み込まれている`forwardRef`関数を使用できます。

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

@Component({
selector: 'my-button',
template: `<div>
<icon></icon>
<input type="button" />
</div>`,
directives: [forwardRef(() => MyIcon)], // MyIcon has not been defined yet
}) // forwardRef resolves as MyIcon when MyIcon is needed
class MyButton {
constructor() {}
}

@Directive({
selector: 'icon',
})
class MyIcon {
constructor(containerButton: MyButton) {} // MyButton has been defined
}

ParamTypeのプロバイダーがありません

No provider for ParamType! (MyClass -> ParamType)

これは、Angularが注入するべき引数の型を知っていても、どのように注入するかわからないことを意味します。

引数がサービスの場合、指定されたクラスをアプリで使用可能なプロバイダーのリストに追加したことを確認してください。

import { MyService } from 'my-service';

@Component({
templateUrl: 'app/app.html',
providers: [MyService], // Don't forget me!
})
class MyApp {}

引数が別のコンポーネントまたはディレクティブ(親コンポーネントなど)の場合、プロバイダーのリストに追加するとエラーはなくなりますが、上記のプロバイダーの複数インスタンスと同じ効果になります。コンポーネントクラスの新しいインスタンスが作成され、目的のコンポーネントインスタンスへの参照を取得できません。代わりに、注入されることを期待しているディレクティブまたはコンポーネントがコンポーネントで使用可能であることを確認してください(たとえば、親であることを期待している場合は実際に親であること)。これは、例を用いると最も理解しやすいでしょう。

@Component({
selector: 'my-comp',
template: '<p my-dir></p>',
directives: [forwardRef(() => MyDir)],
})
class MyComp {
constructor() {
this.name = 'My Component';
}
}

@Directive({
selector: '[my-dir]',
})
class MyDir {
constructor(c: MyComp) {
// <-- This is the line of interest

// Errors when directive is on regular div because there is no MyComp in the
// component tree so there is no MyComp to inject
console.log("Host component's name: " + c.name);
}
}

@Component({
template:
'<my-comp></my-comp>' + // No error in MyDir constructor, MyComp is parent of MyDir
'<my-comp my-dir></my-comp>' + // No error in MyDir constructor, MyComp is host of MyDir
'<div my-dir></div>', // Errors in MyDir constructor
directives: [MyComp, MyDir],
})
class MyApp {}

インジェクターがどのように使用可能であるかを示す図を以下に示します。

                 +-------+
| App |
+---+---+
|
+-------------+------------+
| |
+------+------+ +--------+--------+
| Div (MyDir) | | MyComp (MyDir) | <- MyComp can be injected
+-------------+ +--------+--------+
^ |
No MyComp to inject +------+------+
| P (MyDir) | <- MyComp can be injected from parent
+-------------+

前の例を拡張して、コンポーネント/ディレクティブの参照を常に期待するわけではない場合は、Angularの`@Optional`アノテーションを使用できます。

@Directive({
selector: '[my-dir]',
})
class MyDir {
constructor(@Optional() c: MyComp) {
// No longer errors if c is undefined
if (c) {
console.log(`Host component's name: ${c.name}`);
}
}
}

`propertyName`にバインドできません。既知のプロパティではありません

Can't bind to 'propertyName' since it isn't a known property of the 'elementName' element and there are no matching directives with a corresponding property

これは、そのプロパティを持たない要素のプロパティにバインドしようとすると発生します。要素がコンポーネントであるか、1つ以上のディレクティブを持っている場合、コンポーネントとディレクティブのどちらにもそのプロパティがありません。

<!-- div doesn't have a 'foo' property -->
<div [foo]="bar"></div>

ControlContainerのプロバイダーがありません

No provider for ControlContainer! (NgControlName -> ControlContainer)

このエラーは、上記の`プロバイダーがありません`エラーのより具体的なバージョンです。親のNgFormまたはNgFormModelを指定せずに、NgControlNameのようなフォームコントロールを使用すると発生します。ほとんどの場合、フォームコントロールが実際のフォーム要素内にあることを確認することで解決できます。NgFormは`form`を選択子として使用するため、これにより新しいNgFormがインスタンス化されます。

@Component({
template:
'<form>' +
'<input ngControl="login">' +
'</form>'
})

コンポーネントファクトリが見つかりません

No component factory found for <component name>

このエラーは、インポートされておらず、ngModuleに追加されていないコンポーネント、プロバイダーパイプ、またはディレクティブを使用しようとしたときに発生します。新しいコンポーネント、プロバイダー、パイプ、またはディレクティブをアプリに追加するたびに、Angularが使用できるように、`src/app/app.module.ts`ファイルの`ngModule`に追加する必要があります。このエラーを修正するには、問題のコンポーネント、プロバイダー、パイプ、またはディレクティブをapp.moduleファイルにインポートし、プロバイダーの場合は`providers`配列に追加し、コンポーネント、パイプ、またはディレクティブの場合は`declarations`配列と`entryComponents`配列の両方に追加します。