gregdevs
gregdevs

Reputation: 713

Retrieving values from multiple keys in Firebase using AngularFire2

I am just getting started with angularFire2. I have some Firebase data structured as follows:

{
    "user-friends": {
        "-userkey1": {
            "-userkey2": true,
            "-userkey3": true
        }
    },

    "users": {
        "-userkey1": {
            "uid": "id1",
            "uname": "Jim Yu"
        },
        "-userkey2": {
            "uid": "id2",
            "uname": "Bob Smith"
        },
        "-userkey3": {
            "uid": "id3",
            "uname": "Jane Doe"
        }
    }
}

So far, I can retrieve the data in user-friends node for -userkey1, which returns

   "-userkey1": {
        "-userkey2": true,
        "-userkey3": true
    }

Then I want to be able to get theuname of each key, and store that in a variable that would be bind to the view.

I'm a bit unsure of how to go about that last step specifically using angularFire2..or if there is a angular/firebase specific approach/helper method to solving this.

so far this is what I have, however once I loop through each key and attempt to push the username into an array, the console logs the first keys uname but then screamscannot read property 'push' of undefined

userFriends(userkey: string){
    console.log("userKey=" + userkey)
    var getUsrFriends = this.afDB.list("https://myfirebaseurl.com/user-friends/" + userkey
    ).subscribe( data => {
        data.forEach(friendKey => {
            console.log(friendKey.$key) //my instinct tells me looping through the keys and storing in an array is not a optimal solution
            var getUserInfo = this.afDB.object("https:/myfirebaseurl.com/users/" + friendKey.$key, {
            }).subscribe( u => {
                console.log(u.uname)
                this.friendsList.push(u.uname) // <- undefined error 
            })    
        });       
    })   
}

<ng-container  *ngIf="showView == 'friend'">
    <ion-list *ngFor="let friend of friendsList">
        <h3>{{friend}}</h3>
    </ion-list>
</ng-container>

EDIT: The undefined error was actually caused by not initializing the friendsList Array properly.

export class UserPage {
  friendsList: string[] = []
 // constructor, etc
}

Upvotes: 0

Views: 586

Answers (1)

theblindprophet
theblindprophet

Reputation: 7937

Firebase is really quick, so making multiple calls is not too bad.

Using your current data structure, this code will work:

// Outside firebase calls
let scope = this;

...
var getUserInfo = this.afDB.object("https:/myfirebaseurl.com/users/" + friendKey.$key, {}).take(1).subscribe( u => {
    console.log(u.uname)
    scope.friendsList.push(u.uname) // <- undefined error 
})
...

this, once inside the Firebase promise is reserved by that promise and means something different than the regularly reserved this of global component variables.

Also, use take(1) before the subscribe because you are only wanting to retrieve those values once and not to continue listening.


An alternate method would be to restructure your database to make faster queries in a tradeoff for more data storage. Instead of storing the just the user reference inside user-friends you can store the whole user. But I would advise the first option.

Upvotes: 1

Related Questions