0

Getting null value in callback.. Even i am getting value in console console.log(list).

but i want finallist afetr all forEach operation complete and all csnap.key push to the list

var list = [];
var mkeys = ['-Ka2D86jpdjKpTf2-Nmf', '-KaCPtlIoPX34ltMPqs3'];

   function Getumanes(msgkeys,callback) {
    msgkeys.forEach(function (key) {
        var msgstref = firebase.database().ref("Msgtemplate/" + key + '/Actionusers');
        msgstref.orderByChild('status').equalTo(true).limitToFirst(2).once('value').then(function (snap) {
            snap.forEach(function (csnap) {
                list.push(csnap.key);
            })
            console.log(list);
        })
    })
    callback(list)
}

Getumanes(mkeys, function (finallist) {
    console.log("finallist: " + finallist);
});
SGR Dalal
  • 121
  • 13
  • Firebase tends to collect data asynchronously, so it's likely you're sending the list to console before it's even populated it. You need to wait until the async callback has completed before using the `list`. – Alex Blundell Jan 13 '17 at 13:42
  • Thanx @Alex, can you elaborate How can i achieve that? by piece of some code – SGR Dalal Jan 13 '17 at 13:46
  • Basically the value is calculated inside the callback, the callback is executed after the console.log(list) which mean list is empty then. If you console.log inside the callback you will see the data. That's how async request works. They get called, the rest of the code run and when the request is finished the callback run. – GillesC Jan 13 '17 at 15:33

2 Answers2

1

When accessing the Firebase Database (and pretty much any modern web/cloud API), the call to the back-end happens asynchronously. Instead of waiting for the data to be loaded, the code in your main method continues while the data is being loaded. Then when the data is loaded, your callback function is called.

The easiest way to get to grips with this is by reframing your problem. Instead of thinking "first get the data, then print the data", think of it as "start loading the data, then when the data is available, print it". In code this translated to moving the logic to print the data into the callback:

mkeys.forEach(function (key) {
    var msgstref = firebase.database().ref("Msgtemplate/" + key + '/Actionusers');
    msgstref.orderByChild('status').equalTo(true).limitToFirst(2).once('value').then(function (snap) {
        snap.forEach(function (csnap) {
            list.push(csnap.key);
        })
        console.log(list);
    })
})

And of course console.log in this code could be anything else too.

This problem has been covered a lot before, both for Firebase and for web programming in general. I recommend you study some of these questions and answer, to get to grasp with the concepts of asynchronous web APIs:

As I said... it's a common question. :-)

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanx a lot @Frank van Puffelen, but i want only last array as my result , but currently i am geeting two arrays as i have two vaues from outer forEach, It will be very helpful if you can give some suggesion on it.. – SGR Dalal Jan 16 '17 at 06:31
0

Change you list FROM var list = []; TO list:FirebaseListObservable;

And then in the calling method subscribe to the function that returns this list So that even in the UI the elements get updated accordingly.

DEV
  • 949
  • 1
  • 9
  • 29