Search code examples
angularjsfirebaseionic-frameworkfirebase-realtime-databaseionic2

How to assign snap.val() to the global variable?


I want to assign snap.val() to this.Productslike this.Products= snap.val(); but this.Products is undefined in that scope.

    Products: FirebaseListObservable<any>;
constructor(){

    } 

    ionViewDidLoad(){
      this.angularFire.database.list('/Products').$ref.orderByChild('uid')
     .equalTo('NW1Kq4WB7ReUz2BNknYWML9nF133').on('child_added', function(snap){
                console.log(snap.val().name);
              //this.Products= snap.val();
            });
      }

I tried the following code when snap is returned ,but I receive this message -- No index defined for uid:

snap.forEach(SnapShot=>{
console.log(SnapShot.val().name) 

My Firebase database:

"Products" : {
    "-Kbx0i-TFeTyRbNZAZ_8" : {
      "category" : "1",
      "detail" : "xxxxx details",
      "name" : "xxxxx",
      "uid" : "NW1Kq4WB7ReUz2BNknYWML9nF133"
    }

Please help. Thanks.


Solution

  • The directly answer the question you asked, you can use an ES6 arrow function:

    let query = this.angularFire.database.list('/Products').$ref.orderByChild('uid')
         .equalTo('NW1Kq4WB7ReUz2BNknYWML9nF133');
    query.on('child_added', (snap) => this.Products= snap.val());
    

    Or for ES5 compatibility, declare this as a variable:

    let self = this;
    let query = this.angularFire.database.list('/Products').$ref.orderByChild('uid')
         .equalTo('NW1Kq4WB7ReUz2BNknYWML9nF133');
    query.on('child_added', function(snap) {
       self.Products= snap.val();
    });
    

    But in reality, this is an XY problem and you don't want what you think you want here.

    What you've done is reimplement the list yourself, and defeat the entire purpose of AngularFire2, which handles all this synchronization on your behalf.

    Additionally, you've mis-used child_added by assigning each record you get back (you get an array of results, not exactly one) to this.products, when you probably wanted to set this.products = [] and then use this.products.push(snap.val()) for each child_added invocation.

    So what you really want here, is to use AngularFire's built-in queries and avoid this entire mess :)

    this.products = af.database.list('/Products', {
      query: {
        orderByChild: 'uid',
        equalTo: 'NW1Kq4WB7ReUz2BNknYWML9nF133' 
      }
    });