2

I am having trouble in resolving a promise that is returned by firebase. This is an ionic - angularjs - firebase project that I am building to learn. The issue is that my function returns a promise that contains an array of 3 users but I am unable to unwrap this promise.

Promise returned from firebase query

My code:

function eventusers(id) {
    var userarr = [];
    var deferred = $q.defer();

    // *The code below makes 2 firebase calls and returns an array of users*

    eventref.orderByChild("Eventid").equalTo(eventid).on("value", function(snap) {
        var users = snap.val();
        angular.forEach(users, function(value,key) {
            var obj = value;
            for (var prop in obj) {
                if(obj[prop] == "True") {
                    userref.child(prop).on("value", function (snap) {
                        var id = snap.val().email;
                        userarr.push(id);
                        console.log(userarr); // I am able to see the list of users here
                    });
                };
            }
        });
        deferred.resolve(userarr);
    });
    return deferred.promise;
};

//The console.log shows a promise (pls see the attached pic)
console.log(eventusers(eventid));

// I tried to loop through the response using angular.forEach and also a for loop but it does 
//not execute that part of the code as I do not see the response of the console.log. If I 
//replace the for loop with just console.log(response), then I get an empty array.

eventusers(eventid).then(function (response) {
    for (var i = 0; i <response.length; i++) {
        console.log(response[i]);
    }
});

2 Answers 2

2

Your deferred promise is resolving before the inner asynchronous action

userref.child(prop).on('value', ...

completes.

You'll need to wrap that in another deferred object then return a promise resolving all of the inner promises.

function eventusers(id) {
    return $q(function(resolve) {
        eventRef.orderByChild('Eventid').equalTo(id).on('value', function(snap) {
            var promises = [];
            snap.val().forEach(function(user) {
                angular.forEach(user, function(userProp, prop) {
                    if (userProp === 'True') {
                        promises.push($q(function(resolve) {
                            userref.child(prop).on('value', function(snap) {
                                resolve(snap.val().email);
                            });
                        }));
                    }
                });
            });

            resolve($q.all(promises));
        });
    });
}

eventusers(eventid).then(function (response) {
    for (var i = 0; i < response.length; i++) {
        console.log(response[i]);
    }
});
Sign up to request clarification or add additional context in comments.

Comments

0

Modify your code to

eventusers(eventid).then(function (response) {
var myArray = response.value;
for (var i = 0; i <myArray.length; i++) {
console.log(myArray[i]);
};

Since your array object is inside of promise object


You can also refer to Plunker

2 Comments

OP only pushes emails into userarr which is the resolve value so I'm not sure why you would think they have a value property
Hi Romesh, Thanks for your time. I checked your plunker. myData contains the property 'value' (which is an array of values - ID:1 etc)using which you are able to access it in the getPromiseObject function. My promise object, returns an array containing 3 emails in the pattern: [0: email1, 1: email2, 2: email3].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.