58

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 }}
P_Js
  • 593
  • 1
  • 5
  • 7
  • First i did without like this `ngOnInit() { this.moviesDb.get().subscribe((snap) => { this.movies = snap; console.log(this.movies); }); }` and i had that `InvalidPipeArgument: '[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]' for pipe 'AsyncPipe'` – P_Js Jul 01 '17 at 23:16

7 Answers7

51

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.

Adnan A.
  • 1,932
  • 1
  • 13
  • 18
  • 1
    But you're binding to the emitted value of that Observable, not to the observable itself in the `subscribe` method. `Movies` is not an Observable type, it's `any[]` type. – Adnan A. Jul 01 '17 at 23:22
  • I put `movies: any[]; constructor(private moviesDb: MoviesService) { }` sorry i don't understand it well, so what should i do ? – P_Js Jul 01 '17 at 23:31
  • 2
    Just remove the `async`. Both of them. – Adnan A. Jul 01 '17 at 23:35
  • It's working for Ag-Grid implementation . initaliiy it shows error, So remove | async key from tempalte., – gnganapath May 10 '18 at 16:30
23

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, let's 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.

JGFMK
  • 8,425
  • 4
  • 58
  • 92
19

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 }}
Alex Min
  • 11
  • 3
Nizam Uddin
  • 318
  • 1
  • 9
  • Note that in the latest version of Angular Fire Database, "FirebaseListObservable" has been deprecated. As an alternative, you can use "AngularFireList" instead but note that it's optional if not redundant. `import { AngularFireDatabase , AngularFireList} from '@angular/fire/database'; ` Also, in the latest version of Angular fire instead of using subscribe in the constructor of the component, you use `valueChanges()`. See more https://github.com/angular/angularfire/blob/3e991a61a8d27047e380593e66bea0089e739153/docs/rtdb/lists.md – Kingston Fortune Jun 28 '21 at 20:32
8

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>
Sanjeet kumar
  • 3,333
  • 3
  • 17
  • 26
  • This is the correct answer for anyone looking for the new AngularFireDatabase module that is imported like this: "import { AngularFireDatabase } from '@angular/fire/database';" – Daniel Sep 18 '18 at 14:46
  • Thank you! This is the correct answer for my version-- angularfire2@5.1.1 – Gautham Nookala Jan 31 '19 at 05:14
0

You should add the pipe to the interpolation and not to the ngFor

ul
  li(*ngFor='let movie of (movies)') ///////////removed here///////////////////
    | {{ movie.title | async }}

Reference docs

Aravind
  • 40,391
  • 16
  • 91
  • 110
  • if i remove the async i have this error: `Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.` I did as it was mentionned in the doc of angularfire2: https://github.com/angular/angularfire2 – P_Js Jul 02 '17 at 07:22
  • check the data from service by `console.log` if it is a array of objects or not – Aravind Jul 02 '17 at 07:25
0

Ok I had a similar problem now I solved it so let me explain what you can do but first I don't know which version of angular you are using so the method can be different I am adding my setup version below

Angular CLI: 13.3.1
Node: 16.14.2
Package Manager: npm 8.5.0
OS: win32 x64

Angular: 13.3.1
... animations, cli, common, compiler, compiler-cli, core, forms    
... platform-browser, platform-browser-dynamic, router

Package                         Version

    @angular-devkit/architect       0.1303.1
@angular-devkit/build-angular   13.3.1
@angular-devkit/core            13.3.1
@angular-devkit/schematics      13.3.1
@angular/fire                   7.3.0
@schematics/angular             13.3.1
rxjs                            7.5.5
typescript                      4.6.3

1 First change is your service file, change it from

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';

    @Injectable()
    export class MoviesService {

      constructor(private db: AngularFireDatabase) {}
      get = () => this.db.list('/movies');
    }

To this,

    import { Injectable } from '@angular/core';
    import { AngularFireDatabase } from 'angularfire2/database';

    @Injectable()
    export class MoviesService {

      constructor(private db: AngularFireDatabase) {}
      get(): Observable<any[]>{
          return this.db.list('/movies')
      } 
    }

Note:- Don't forget to import Observable from proper module

Then change your component from this

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

To something like this

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.movies$ = this.moviesDb.get()
        .subscribe((snaps) => {
          snaps.forEach((snap) => {
            this.movies$ = snap;
            console.log(this.movies$);
          });
       });
     }
    }

And your last file from this

ul
   li(*ngFor='let movie of (movies | async)')
      | {{ movie.title | async }}

To this

ul
    li(*ngFor='let movie of (movies | async)')
        | {{ movie.title }}

I am not a pro but I solved it this way and hope it works for you too

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
smit agravat
  • 223
  • 2
  • 9
0

Observables > Signals

If you have been converting code from using Observable to signal you may come across the following variation of the error:

Error: NG02100: InvalidPipeArgument: 'function () { [native code] }' for pipe 'AsyncPipe'

The 'native code' part looks a little scary at first but it is simply the string representation of a signal with its unique Symbol.

Simple click on the first line of code in the error message that looks like yours, to find where in the template you switched to using a signal but didn't update the async pipe.

enter image description here

So before you may have had:

favoriteColor: Observable<string>;

{{ favoriteColor | async }}

Now as a signal it should be:

favoriteColor: Signal<string>;

{{ favoriteColor() }}
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689