Reputation: 1895
I am trying to build a simple blog with Angular 2 and Firebase and I am having issues using async pipe in a component. I get the error in the console.
zone.js:344Unhandled Promise rejection: Template parse errors: The pipe 'async' could not be found ("
[ERROR ->]{{ (blog.user | async)?.first_name }}
"): BlogComponent@6:3 ; Zone: ; Task: Promise.then ; Value: Error: Template parse errors:(…) Error: Template parse errors: The pipe 'async' could not be found ("
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;
});
});
}
}
The problem arises only when I try to use async in blog.component.html file. It works if I try to print the user name in app.component.html file. Should I be injecting AsyncPipe in blog.module.ts? How can I get the async working in blog.component.ts?
Upvotes: 168
Views: 192059
Reputation: 54579
If like me you're developing a standalone component,
I was missing the import
import { AsyncPipe } from '@angular/common';
@Component({
selector: 'test',
standalone: true,
imports: [
AsyncPipe
],
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
Upvotes: 18
Reputation: 344
If you are using a STANDALONE component, add "CommonModule" to the imports[CommonModule] @Component metadata.
e.g.
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'a-standalone-component',
standalone: true,
imports: [CommonModule],
template: `testMsg$ {{testMsg$ | async}}
Upvotes: 1
Reputation: 179
Changing the name of a component could also cause this error, and you can solve this by manually checking the imports in the app module, because it will probably be messed up.
Upvotes: 0
Reputation: 21259
Basic reason:
The pipe async
is exported from the CommonModule
and you will get this error when you forgot to import CommonModule
either in the module importing your component or in the component itself (if you are in standalone mode.
Advanced one:
Now you might also get the "pipe async not found" if angular, for some reason, has not been able to preload properly the CommonModule
.
To check if this is the case, you can force Angular preloading all the modules, changing your code as follows:
// Probably in app-routing.module.ts
import { RouterModule, PreloadAllModules } from '@angular/router';
RouterModule.forRoot([
], {
// Add this property to your main router module
preloadingStrategy: PreloadAllModules
})
Then reload the page, if the problem is gone, it very likely means angular is not able to resolve your routes dependencies properly. You could for instance have a module importing its routes but also importing another module itself importing its routes.
Upvotes: 3
Reputation: 169
Also, make sure that you're importing the module that the component is declared in.
Upvotes: 0
Reputation: 575
Previous answers are good (remember to do declarations:[]
), but also remember to restart your watch (only if you're using CMD npm-run webpack-development -- -- progress --watch
.
Upvotes: 1
Reputation: 11
I faced this issue when I tried to use the async pipe in a component used as a dialog. I solved this by declaring the component in the immediate module (I used lazy loading). The app module if you are not.
Upvotes: 0
Reputation: 2402
Component you're trying to load is not declared in the declarations array then you will get this type of error, in my case this was shipping component, like mentioned below:
Upvotes: 19
Reputation: 1769
edit: I have been doing my own project, and I have noticed that this error might occur when code has any kind of build error, for example unclosed html tag like <label>foo<label>
. After that, the only way I know, is to just reset the entire server. It is annoying and shouldn't be like that.
I got this error when I had an empty (actually commented) function implementation in my component
in html:
<div (click)="onClickFoo()">
in .ts
onClickFoo() {
// this.router.navigate([...])
}
Upvotes: 3
Reputation: 1846
In my case the input to the pipe was null.
So in the case of the question make sure that blog.user
in <p>{{ (blog.user | async)?.first_name }}</p>
is not null.
Upvotes: 6
Reputation: 145880
If you're getting this in an optimized production build it could be due to tree shaking, especially if you're using sideEffects: false
. This is now an encouraged setting in Angular 10 via ng new --strict
.
Still have yet to figure out how to fix my project, but setting it to true fixed it for me for now.
Upvotes: 1
Reputation: 10849
If the component at the route you're loading is not declared (via declarations:[]
) then you will also get this type of error.
Upvotes: 77
Reputation: 544
If you tried all above mentioned answers but it is not working means , Just do npm run start
it will work ,
In my case after some compilation issue this error came.
Upvotes: 16
Reputation: 741
I found the same problem some times when changing multiple imports at once.
My app worked back again just fine without changing any code but restarting ng start
. One of the surprises of coding until late.
Normally this drives me crazy as I was checking all the imports, and the answer of the "Common Module" normally makes sense, but just in case someone finds the same silly situation I faced, now you know what to do.
Upvotes: 7
Reputation: 23078
When adding a new component in Angular 9 I had to restart the development server possibly also because of HMR:
ng serve --hmr
Without this the application simply did not load all the dependencies and issued this error.
Upvotes: 22
Reputation: 449
If you have upgraded to Angular 6 or 7, make sure in your tsconfig.ts turn off enableIvy in angularCompilerOptions
e.g:
angularCompilerOptions: {
enableIvy : false; // default is true
}
That solved my issue, may be it'll save someone else time too.
Upvotes: 10
Reputation: 6416
You can also get the same error if you are using multiple modules in your 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 {}
Then if you generate a component using the command:
ng generate component example
It gets added to the first module, instead of the second one:
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 {}
Which will create the same error! Moving the component to the AppModule will fix it.
@NgModule({
imports: [MaterialModule]
declarations: [AppComponent, ExampleComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
Upvotes: 1
Reputation: 208944
@NgModule.declarations
aren't inherited by child modules. If you need pipes, directives, components from a module, the module should be imported into your feature module.
The module with all the core pipes is CommonModule
from @angular/common
import { CommonModule } from '@angular/common';
@NgModule({
imports: [ CommonModule ]
})
class BlogModule {}
The reason it works in the app.component
is because you are most likely importing BrowserModule
into the AppModule
. BrowserModule
re-exports CommonModule
, so by importing BrowserModule
, it's like also importing CommonModule
.
It's also worth noting that CommonModule
has the core directives also, like ngFor
and ngIf
. So if you have a feature module that uses those, you will also need to import the CommonModule
into that module.
Upvotes: 257