Search code examples
angularfirebaseasynchronousangularfire2

Firebase async error : InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'


I am fetching list of categories from firebase using angularfire. Here is the JSON export of database.

{
  "categories" : {
    "bread" : {
      "Name" : "Bread"
    },
    "fruits" : {
      "Name" : "Fruits"
    },
    "seasonings" : {
      "Name" : "Seasonings"
    }
  },
  "users" : {
    "8ji3HjnPD0es5K5rNj2jHpPWeEk1" : {
      "email" : "abc@gmail.com",
      "isAdmin" : true,
      "name" : "Kartik Dolas"
    }
  },
  "vegetables" : {
    "Name" : "Vegetables"
  }
}

service.ts

import { AngularFireDatabase } from 'angularfire2/database';
...
    constructor(private db:AngularFireDatabase) { }
      getCategories(){
        return this.db.list('/categories')  
      }

component.ts

export class PrductFormComponent implements OnInit {
categories$;

  constructor(categServ:CategoryService) {
    this.categories$ = categServ.getCategories()
    console.log(this.categories$);
    
   }

  ngOnInit(): void {
  }

}

component.html

<div class="form-group">
    <label for="category">Category</label>
    <select id="category" class="form-control">
      <option value=""></option>
      <option *ngFor="let c of categories$ | async" [value]="c.$key">
        {{ c.name }}
      </option>
    </select>
  </div>

I am using firebase version 7.24 and angularfire2 version 5.4.2. I want my output to be dropdown of Bread,Fruits,Seasonings but I am getting an error : InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'


Solution

  • This should work.
    component.html

    <div class="form-group">
        <label for="category">Category</label>
        <select id="category" class="form-control">
          <option value=""></option>
          <option *ngFor="let c of categories$ |async" value="c.$key">
            {{ c.Name }}
          </option>
        </select>
      </div>
    

    service.ts

    getCategories(): Observable<any>{
        // add valueChanges() here
        return this.db.list('categories').valueChanges();  
      }
    

    If $key is not working for any version, use snapshotchanges instead.
    service.ts

    getCategories() {
        return this.db
            .list('/categories', (ref) => ref.orderByChild('name'))
            .snapshotChanges()
            .pipe(
            map((actions) => {
                return actions.map((action) => ({
                    key: action.key,
                    val: action.payload.val(),
                }));
            }));
    
    }
    

    component.html

    <option *ngFor="let c of categories$ | async" [value]="c.key">
        {{ c.val.name }}
    </option>