Angular 4: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'
i need your help, i'm trying to display some datas from my firebase but it trhows me an error like InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'
.
There is my service:
import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
@Injectable()
export class MoviesService {
constructor(private db: AngularFireDatabase) {}
get = () => this.db.list('/movies');
}
There is my component:
import { Component, OnInit } from '@angular/core';
import { MoviesService } from './movies.service';
@Component({
selector: 'app-movies',
templateUrl: './movies.component.html',
styleUrls: ['./movies.component.css']
})
export class MoviesComponent implements OnInit {
movies: any[];
constructor(private moviesDb: MoviesService) { }
ngOnInit() {
this.moviesDb.get().subscribe((snaps) => {
snaps.forEach((snap) => {
this.movies = snap;
console.log(this.movies);
});
});
}
}
And there is mmy pug:
ul
li(*ngFor='let movie of (movies | async)')
| {{ movie.title | async }}
Solution 1:
async
is used for binding to Observables and Promises, but it seems like you're binding to a regular object. You can just remove both async
keywords and it should probably work.
Solution 2:
You get this message when you've used async in your template, but are referring to an object that isn't an Observable.
So for examples sake, lets' say I had these properties in my class:
job:Job
job$:Observable<Job>
Then in my template, I refer to it this way:
{{job | async }}
instead of:
{{job$ | async }}
You wouldn't need the job:Job property if you use the async pipe, but it serves to illustrate a cause of the error.
Solution 3:
In your MoviesService you should import FirebaseListObservable in order to define return type FirebaseListObservable<any[]>
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
then get() method should like this-
get (): FirebaseListObservable<any[]>{
return this.db.list('/movies');
}
this get() method will return FirebaseListObervable of movies list
In your MoviesComponent should look like this
export class MoviesComponent implements OnInit {
movies: any[];
constructor(private moviesDb: MoviesService) { }
ngOnInit() {
this.moviesDb.get().subscribe((snaps) => {
this.movies = snaps;
});
}
}
Then you can easily iterate through movies without async pipe as movies[] data is not observable type, your html should be this
ul
li(*ngFor='let movie of movies')
{{ movie.title }}
if you declear movies as a
movies: FirebaseListObservable<any[]>;
then you should simply call
movies: FirebaseListObservable<any[]>;
ngOnInit() {
this.movies = this.moviesDb.get();
}
and your html should be this
ul
li(*ngFor='let movie of movies | async')
{{ movie.title }}
Solution 4:
I found another solution to get the data. according to the documentation Please check documentation link
In service file add following.
import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
@Injectable()
export class MoviesService {
constructor(private db: AngularFireDatabase) {}
getMovies() {
this.db.list('/movies').valueChanges();
}
}
In Component add following.
import { Component, OnInit } from '@angular/core';
import { MoviesService } from './movies.service';
@Component({
selector: 'app-movies',
templateUrl: './movies.component.html',
styleUrls: ['./movies.component.css']
})
export class MoviesComponent implements OnInit {
movies$;
constructor(private moviesDb: MoviesService) {
this.movies$ = moviesDb.getMovies();
}
In your html file add following.
<li *ngFor="let m of movies$ | async">{{ m.name }} </li>