Invalid argument for pipe 'AsyncPipe'

34,069

Solution 1

The async pipe expects an observable or a promise. http.get and map operator return observable, so you can set the returned object into the listItems property of your component. You don't need to subscribe in this case:

this.listItems = this._firebaseService.getResources();

Moreover the object, this element will "receive" must be an array to be able to use it within an ngFor. You service returns an object and not an array from Firebase. If you want to iterate over the keys of the object, you need to implement a custom pipe:

@Pipe({name: 'keys'})
export class KeysPipe implements PipeTransform {
  transform(value, args:string[]) : any {
    let keys = [];
    for (let key in value) {
      keys.push({key: key, value: value[key]);
    }
    return keys;
  }
}

and use it like this:

@Component({
  selector: "arc-list",
  template: `
  <ul class="arc-list">
    <li *ngFor="#item of listItems | async | keys" class="arc-item">
      <h3>{{ item.value.name}}</h3><a [href]="item.value.resourceUrl" target="_blank" class="btn btn-success pull-right"><span>Go</span></a>
      <hr>
      <blockquote>{{ item.value.description }}</blockquote>
      <hr>

    </li>
  </ul>
  `,
  pipes: [ KeysPipe ]
})

See this question for more details:

Solution 2

async pipe works with observables and/or promises. It does subscription for you, so you just have to pass an observable without subscribing to it in your code:

  ngOnInit(): any {
    this.listItems = this._firebaseService.getResources()
  }
Share:
34,069
Petros Kyriakou
Author by

Petros Kyriakou

I am a web-developer enthusiast with a keen interest on the latest web technologies and passionate around backend magic. #SOreadytohelp

Updated on July 05, 2020

Comments

  • Petros Kyriakou
    Petros Kyriakou almost 4 years

    So i get this when i try to get my data from firebase

    Invalid argument '{"-KCO4lKzEJPRq0QgkfHO":{"description":"teste","id":1457488598401,"resourceUrl":"tete","title":"test2"}}' for pipe 'AsyncPipe' in [listItems | async  in ArcListComponent@2:10]
    

    ArcListComponent

    import { Component, OnInit } from "angular2/core";
    import { FirebaseService } from "../shared/firebase.service";
    import { ArcItem } from "./arc-item.model";
    
    
    @Component({
        selector: "arc-list",
        template: `
        <ul class="arc-list">
          <li *ngFor="#item of listItems | async " class="arc-item">
            <h3>{{ item.name}}</h3><a [href]="item.resourceUrl" target="_blank" class="btn btn-success pull-right"><span>Go</span></a>
            <hr>
            <blockquote>{{ item.description }}</blockquote>
            <hr>
    
          </li>
        </ul>
        `
    
    })
    
    export class ArcListComponent implements OnInit {
      listItems: string;
    
      constructor(private _firebaseService: FirebaseService) {}
    
      ngOnInit(): any {
        this._firebaseService.getResources().subscribe(
          resource => this.listItems = JSON.stringify(resource),
          error => console.log(error)
        );
      }
    
    }
    

    firebase_service

    import { Injectable } from "angular2/core";
    import { Http } from "angular2/http";
    import "rxjs/Rx";
    
    @Injectable()
    export class FirebaseService {
    
      constructor(private _http: Http) {}
    
      setResource(id: number, title: string, description: string, resourceUrl: string) {
        const body = JSON.stringify({ id: id, title: title, description: description, resourceUrl: resourceUrl});
    
        return this._http
                         .post("https://######.firebaseio.com/resource.json", body)
                         .map(response => response.json());
      }
    
      getResources() {
        return this._http
                         .get("https://######.firebaseio.com/resource.json")
                         .map(response => response.json());
      }
    }
    

    I know i am trying to show my data the wrong way but i do not know how to fix this. any help appreciated.

  • Petros Kyriakou
    Petros Kyriakou about 8 years
    Hello thank you for your comments, now i get this Cannot find a differ supporting object '[object Object]' in [listItems | async in ArcListComponent@2:10] Note that i had to change my listItems type to Observable<any> also.
  • Eric Martinez
    Eric Martinez about 8 years
    @PetrosKyriakou your Observable/Promise must return an array, NgFor doesn't iterate over objects.
  • Petros Kyriakou
    Petros Kyriakou about 8 years
    @EricMartinez is there an example of you what you mean? i am new to this kind of stuff. I mean i understand what you say just do not know how to do it
  • garethb
    garethb over 7 years
    Does this also then mean I don't need to call unsubscribe as it's handled by the framework?
  • Muirik
    Muirik about 7 years
    The Async pipe automatically handles subscription and unsubscription for you.