Exception on filtered Firebase json data


#1

Hi there,
i am a newbie on Ionic 2 and Angular 2. I try to learn and and make a simple app.
My Data are stored in Firebase and i am able to read and show the data in a simple master/detail view.

My problem is, when i add a firebase filter to the url (url.json + “?orderBy=“lh_id”&equalTo=1”) then i get this Exception:

EXCEPTION: Cannot find a differ supporting object ‘[object Object]’ of type ‘object’. NgFor only supports binding to Iterables such as Arrays.

With this code, it works:

    this.http.get('https://blabla.firebaseio.com/blabla.json')
            .map(res => res.json())
            .subscribe(data => {
              // we've got back the raw data, now generate the core schedule data
              // and save the data for later reference
              this.data = data;
            });

but when i change the url to

                this.http.get('https://blabla.firebaseio.com/blabla.json?orderBy="lh_id"&equalTo=1')
             .map(res => res.json())
             .subscribe(data => {
               // we've got back the raw data, now generate the core schedule data
               // and save the data for later reference
               this.data = data;
             });

and try to list the data, then i get the Exception.
console.log(this.data) works with both versions.

I hope you can point me to the right direction. Thank you in advance

iamDoerr


All arrays are objects, but not all objects are arrays
#2

I guess that Firebase returns an object which you have to convert to Array in order to iterate over it with NgFor.


#3

Hi iignatov,
thanks for answer. When i log it in the console i get the same object as without the filter in the url.
I tried also to define a Array (var blabla [ ] = this.data;) but without a result. Or is my try to convert false?
When i put the url in the browser, i get by both urls a clean json as result.

I tried also an other way to bypass the problem with your tip in a other tread -->

@Page(
// …
)
export class TestPage {
// …
getActiveItems() {
// NOTE: Returning a new array might mess up the change detection of Ng2.
// TODO: Use an existing array instead of returning a new one each time.
return this.items.filter(item => !item.deleted);
}
}

but there i got error with undefined filter (i am a noobish newbie :frowning: )

Is there any other way to filter a json?

Thank you in advance
iamDoerr


#4

you need to convert the snapshot from Firebase into an Array…

getDataObs(_id) {
    var ref = this.baseRef.child('bookItems')
    //  ref = ref.child(_id)
    var that = this

    return new Observable(observer => {
        ref.on('value',
            (snapshot) => {
                var arr = []

                snapshot.forEach(function(childSnapshot) {
                    arr.push({
                        id: childSnapshot.key(),
                        data: childSnapshot.val()
                    });
                });
                observer.next(arr)
            },
            (error) => {
                console.log("ERROR:", error)
                observer.error(error)
            });
    });
}

The calling code

this.FBService.getDataObs(data.uid)
    .subscribe((data: Array<any>) => {
        console.log(data)
        this.items = data
    })
});

The html

<ion-content class="home">
    <h3 padding>Active User: {{activeUser}}</h3>
    <button (click)="doLogout()">Logout</button>
    <ion-card *ngFor="#item of items">
        <ion-card-header>
            {{item.data.volumeInfo.title}}
        </ion-card-header>
        <ion-card-content>
            {{item.data.volumeInfo.description}}
        </ion-card-content>
    </ion-card>
</ion-content>

Full Solution


#5

AFAIK the data returned by Firebase is a JSON object (because Firebase has no native support for arrays) so you have to convert it to an array:

            .subscribe(data => {
              // we've got back the raw data, now generate the core schedule data
              // and save the data for later reference
              this.data = [];
              if (data) {
                for (let id of Object.keys(data)) {
                  this.data.push(data[id]);
                }
              }
            });

EDIT: Or just use the Firebase JS client, as shown in the great example by @aaronksaunders.


#6

@iignatov
You are my HERO!
It works now perfectly, thank you so much.
In the next Days i will also try the example from @aaronksaunders !
I see, i have much to learn :slight_smile:
Thank you both