web-dev-qa-db-fra.com

Le tuyau «async» est introuvable

J'essaie de créer un blog simple avec Angular 2 et Firebase et j'ai des problèmes avec le canal asynchrone dans le composant. J'obtiens l'erreur dans la console.

zone.js: 344Réjection de promesse non gérée: erreurs d'analyse du modèle: le canal 'async' est introuvable ("

[ERREUR ->] {{(blog.user | async) ?. prénom_}}

"): BlogComponent @ 6: 3; Zone:; Tâche: Promise.then; Valeur: Erreur: Erreurs d'analyse de modèle: (…) Erreur: Erreurs d'analyse de modèle: Le canal 'async' est introuvable ("

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

Le problème se pose uniquement lorsque j'essaie d'utiliser async dans le fichier blog.component.html. Cela fonctionne si j'essaie d'imprimer le nom d'utilisateur dans le fichier app.component.html. Dois-je injecter AsyncPipe dans blog.module.ts? Comment puis-je faire fonctionner l'async dans blog.component.ts?

25
Balaji

@NgModule.declarations ne sont pas hérités par les modules enfants. Si vous avez besoin de tuyaux, de directives, de composants d'un module, le module doit être importé dans votre module d'entités.

Le module avec tous les tuyaux principaux est CommonModule de @angular/common

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

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

La raison pour laquelle cela fonctionne dans le app.component est parce que vous importez très probablement BrowserModule dans le AppModule. BrowserModule réexporte CommonModule, donc en important BrowserModule, c'est comme importer également CommonModule.

Il convient également de noter que CommonModule a également les directives de base, comme ngFor et ngIf. Donc, si vous avez un module de fonctionnalités qui les utilise, vous devrez également importer le CommonModule dans ce module.

69
Paul Samsotha

Si vous avez mis à niveau vers Angular 6 ou 7, assurez-vous dans votre tsconfig.ts désactivez enableIvy dans angularCompilerOptions

par exemple:

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

Cela a résolu mon problème, peut-être que cela fera gagner du temps à quelqu'un d'autre.

11
Nadeem

Vous pouvez également obtenir la même erreur si vous utilisez plusieurs modules dans votre 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 {}

Ensuite, si vous générez un composant à l'aide de la commande:

ng generate component example

Il est ajouté au premier module, au lieu du second:

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

Ce qui créera la même erreur! Le déplacement du composant vers AppModule le corrigera.

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