asynchronous callback returns null

2019-09-01 07:24发布

问题:

I am trying to assign callback function values and display ng-repeat

var myApp = angular.module('mybet',[]);

myApp.controller('MyBetController', function($scope,$firebase,ProfileFactory,MybetFactory){

    $scope.myBetEvents = MybetFactory.getUsersBetsProfile(currentLoggedUser, function(betsData){
        //Callback retuning null value here
        $scope.myBetEvents = betsData;
    });

});

myApp.factory('MybetFactory', ['$firebase', function($firebase){

    var factory = {};

    factory.getUsersBetsProfile = function(userId, callback){

        var firebaseRef = new Firebase("https://xxx.firebaseio.com/usersbetsprofile").child(userId);
        var firebaseBetsRef = new Firebase("https://xxx.firebaseio.com/events");
        var userBettedEvent = [];
        //retrive the data
        firebaseRef.on('value', function (snapshot) {
            console.log(snapshot.val());
            var data = snapshot.val();
            if (data){
                //callback(data);
                angular.forEach(data, function(data){
                    console.log('For Each getUsersBets',data);
                    var firebaseEventsData = firebaseBetsRef.child(data.event_id);
                    //retrive the data of bets
                    firebaseEventsData.on('value', function (snapshot) {    
                        userBettedEvent.push(snapshot.val());
                        console.log('userBettedEvent',userBettedEvent);
                        //if I call callback here then i get the values but calling callback multipul time is no the option 
                }, function (errorObject) {
                    console.log('The read failed: ' + errorObject.code);
                    });
                });
                //ISSUE:: callback returing null values
                        callback(userBettedEvent);
            }else{
                console.log('Users has no bets');
            }
        }, function (errorObject) {
            console.log('The read failed: ' + errorObject.code);
            });
    };

    return factory;
}])

View::

<ul class="list">
        <li class="item" ng-repeat="events in myBetEvents">{{events.event_name}}</li>
 </ul>

How can get callback() to return values and display in view? what is causing callback after foreach returning null?

回答1:

As @coder already said in the comments, your callback(userBettedEvent) is in the wrong place. Where you have it now, it will be invoked before the on('value' from Firebase has completed.

From the comments it is clear that you've notice that, yet only want the callback to invoked for one child. You can simply use a limit for that.

Something like this would work:

if (data){
    data.limit(1).on('value', function(childData) {
        var firebaseEventsData = firebaseBetsRef.child(childData.event_id);
        firebaseEventsData.on('value', function (snapshot) {    
            userBettedEvent.push(snapshot.val());
            callback(userBettedEvent);
        }
    })

I haven't really tested the code, but I'm quite sure a limit should get you in the right direction.

As a side note: you seem to be using Firebase as a traditional database, pulling the data out like you'd do with SQL. As you may notice: that is not a natural model for Firebase, which was made to synchronize data changes. If you want to stick to pulling the data, you may consider using once('value' instead of on('value' to ensure the handlers fire only once for every time you try to pull the data from Firebase.