web-dev-qa-db-ja.com

パイプ「非同期」が見つかりませんでした

Angular 2とFirebaseを使用して簡単なブログを作成しようとしていますが、コンポーネントで非同期パイプを使用すると問題が発生します。コンソールにエラーが表示されます。

zone.js:344未処理のプロミス拒否:テンプレート解析エラー:パイプ「非同期」が見つかりませんでした( "

[エラー->] {{(blog.user | async)?. first_name}}

"):BlogComponent @ 6:3;ゾーン:;タスク:Promise.then;値:エラー:テンプレート解析エラー:(…)エラー:テンプレート解析エラー:パイプ 'async'が見つかりません("

blog.component.ts

import {Component, Input} from "@angular/core";

@Component({
  selector: 'blog-component',
  templateUrl: './blog.component.html',
  styleUrls: ['./blog.component.css'],
})

export class BlogComponent {
  @Input() blog;
}

blog.component.html

<h1 class="article-title">{{ blog.title }}</h1>

<p>{{ (blog.user | async)?.first_name }}</p>

app.component.ts

import { Component } from '@angular/core';
import { BlogService } from "./services/services.module";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  constructor(private blogService: BlogService) {}
  articles = this.blogService.getAllArticles();
}

app.component.html

<article *ngFor="let article of articles | async">
<blog-component [blog]="article"></blog-component>
</article>

blog.service.ts

import {Injectable} from "@angular/core";
import {AngularFire} from "angularfire2";
import {Observable} from "rxjs";
import "rxjs/add/operator/map";


@Injectable()
export class BlogService {

  constructor(private af: AngularFire) { }

  getAllArticles(): Observable<any[]> {
    return this.af.database.list('articles', {
      query: {
        orderByKey: true,
        limitToLast: 10
      }
    }).map((articles) => {
      return articles.map((article) => {
        article.user = this.af.database.object(`/users/${article.user_id}`);
        return article;
      });
    });
  }
}

この問題は、blog.component.htmlファイルで非同期を使用しようとしたときにのみ発生します。 app.component.htmlファイルでユーザー名を印刷しようとすると機能します。 blog.module.tsにAsyncPipeを注入する必要がありますか? blog.component.tsで非同期を機能させるにはどうすればよいですか?

25
Balaji

@NgModule.declarationsは、子モジュールに継承されません。パイプ、ディレクティブ、モジュールのコンポーネントが必要な場合、モジュールを機能モジュールにインポートする必要があります。

すべてのコアパイプを含むモジュールは、@angular/commonからのCommonModuleです。

import { CommonModule } from '@angular/common';

@NgModule({
  imports: [ CommonModule ]
})
class BlogModule {}

app.componentで機能する理由は、BrowserModuleAppModuleにインポートする可能性が高いためです。 BrowserModuleCommonModuleを再エクスポートするため、BrowserModuleをインポートすることは、CommonModuleもインポートするようなものです。

CommonModuleには、ngForngIfなどのコアディレクティブも含まれていることにも注意してください。したがって、それらを使用する機能モジュールがある場合は、CommonModuleもそのモジュールにインポートする必要があります。

69
Paul Samsotha

Angular 6または7にアップグレードした場合、tsconfig.tsでenableIvyをオフにしてくださいangularCompilerOptions

例えば:

angularCompilerOptions: {
enableIvy : false; // default is true
}

これで私の問題は解決しました。誰かの時間も節約できるかもしれません。

11
Nadeem

App.module.tsで複数のモジュールを使用している場合も、同じエラーが発生する可能性があります

import { MatCardModule } from '@angular/material';
import { AppComponent } from './app.component';

// module 1
@NgModule({ exports: [MatCardModule] })
export class MaterialModule {}

// module 2
@NgModule({
    imports: [MaterialModule]
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule {}

次に、コマンドを使用してコンポーネントを生成する場合:

ng generate component example

2番目のモジュールではなく、最初のモジュールに追加されます。

import { MatCardModule } from '@angular/material';
import { AppComponent } from './app.component';
import { ExampleComponent } from './example/example.component';

// module 1
@NgModule({ exports: [MatCardModule], declarations: [ExampleComponent] })
export class MaterialModule {}

// module 2
@NgModule({
    imports: [MaterialModule]
    declarations: [AppComponent],
    bootstrap: [AppComponent]
})
export class AppModule {}

同じエラーが発生します!コンポーネントをAppModuleに移動すると修正されます。

@NgModule({
    imports: [MaterialModule]
    declarations: [AppComponent, ExampleComponent],
    bootstrap: [AppComponent]
})
export class AppModule {}
1
Kim T