简体   繁体   中英

Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables

I've been following an Ionic tutorial made by a content creator named Paul Halliday. The project is a shopping list that uses Firebase and Angular.

My problem is that whenever I run the app, I receive an error that looks like the following:

Error: Uncaught (in promise): Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

I've tried to look through other examples of how to fix my code, but none of them seem to comply with my code.

Currently, my page's Ts file is titled shopping.ts

 import { Component } from '@angular/core'; import { NavParams, NavController } from 'ionic-angular'; import { AddShoppingPage } from '../addshopping/addshopping'; import { AngularFireDatabase} from 'angularfire2/database'; import { Observable } from 'rxjs/Observable'; import { ShoppingItem } from 'src/models/shopping-item/shopping-item.interface'; @Component({ selector: 'page-shopping', templateUrl: 'shopping.html' }) export class ShoppingPage { shoppingListRef$: Observable<ShoppingItem[]>; constructor(public navCtrl: NavController, public navParams: NavParams, private database: AngularFireDatabase ) { this.shoppingListRef$ = this.database.list('shopping-list').valueChanges(); } navigate2AddShoppingPg() { this.navCtrl.push(AddShoppingPage); } } 

There is also an interface that we have defined through a ts file:

export interface ShoppingItem {
itemName: string;
itemNumber: number;
}

Finally, the html of our shopping page is:

 <ion-header> <ion-navbar> <ion-title>Shopping List</ion-title> <ion-buttons end> <button (click)="navigate2AddShoppingPg()"> <ion-icon name="add"></ion-icon> </button> </ion-buttons> </ion-navbar> </ion-header> <ion-content padding> <ion-list> <ion-item *ngFor = "let item of shoppingListRef$"> <h2>Item Name: {{item.itemName}}</h2> <h3>Quantity: {{item.itemNumber}}</h3> </ion-item> </ion-list> </ion-content> 

Any help would be super appreciated. Thank you!!

Edit 2 ~~three months after~~ I haven't visited this question in a while, but to avoid being misleading to those seeking a solution, yes, the async pipe is actually supported.

Your shoppingListRef$ does not represent any iterable type for Angular. It's Observable<ShoppingItem[]> , whereas Observable by itself is uniterable. What you are trying to do is to iterate over value returned from the observable. Try something like below:

/* controller field */
listItems: ShoppingItem[] = [];

this.database.list('shopping-list').valueChanges()
.subscribe((v: ShoppingItem[]) => {
  this.listItems = v.slice(0);
})

And in template:

    <ion-item *ngFor = "let item of listItems">
        <h2>Item Name: {{item.itemName}}</h2>
        <h3>Quantity: {{item.itemNumber}}</h3>
    </ion-item>

And as mentioned by @user184994 you can as well use async on template, which basically under the hood will subscribe to observable and pass forward returned values.
One remark, if you wish your view to keep in sync with data, this component change detection strategy can not be set to onPush

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM