Updated scope variable not showed by view. Promises not working

时间:2016-10-20 12:42:07

标签: javascript angularjs firebase firebase-realtime-database angularfire

I'm trying to retrieve data from my Firebase Database, and corresponding images from Firebase Storage. The problem is, my view does not want to update itself with the data.

If I try to simply fetch the data from my database, it works perfectly. Once I add functionality to fetch pictures (which takes slightly longer) it looks like my view simply looks immediately at the scope variable and does not wait for $scope.friendsinfo to update. I think I'm doing something wrong with my promises and should be using $q, but I have no idea how exactly. Can anyone tell me what the best way would be to go about this? Thanks a lot!

var friendsRef = firebase.database().ref('friendships/' + firebase.auth().currentUser.uid);

$scope.friends = $firebaseArray(friendsRef);

$scope.friendsinfo = [];

$scope.$watch('friends', function() {
    var newfriends = $scope.friends;
    var newfriendsinfo = [];

    for(var i = 0; i < newfriends.length; i++){
        var ref = firebase.database().ref('users/' + newfriends[i].$id);
        var profilePicRef = firebase.storage().ref("profilepictures/" + newfriends[i].$id + "/profilepicture");
        var picPromise = fetchPicture(profilePicRef);

        var newfriendid = newfriends[i].$id;
        var newfriendagreed = newfriends[i].agreed;

        picPromise.then(function(data){
            ref.once('value', function(snapshot){
                newfriendsinfo.push({
                    id: newfriendid,
                    name: snapshot.val().name,
                    email: snapshot.val().email,
                    agreed: newfriendagreed,
                    profilepicture: data //This is the functionality that causes my view to not display the updated $scope.friendsinfo because it takes too long.
                });
            });
        });
    }
    $scope.friendsinfo = newfriendsinfo;
    alert($scope.friendsinfo.length);
}, true);

function fetchPicture(ref){
    return ref.getDownloadURL().then(function(url) {
        return url;
    }).catch(function(error) {
        alert("error");
    });
}

2 个答案:

答案 0 :(得分:0)

I have not got your code properly but posting code which will you to guide that how to use promises with resolve approach :

  function asyncGreet(name) {
  var deferred = $q.defer();

  setTimeout(function() {
  deferred.notify('About to greet ' + name + '.');

  if (okToGreet(name)) {
  deferred.resolve('Hello, ' + name + '!');
  } else {
      deferred.reject('Greeting ' + name + ' is not allowed.');
  }
  }, 1000);

  return deferred.promise;
}

var promise = asyncGreet('Robin Hood');
promise.then(function(greeting) {
  alert('Success: ' + greeting);
}, function(reason) {
  alert('Failed: ' + reason);
}, function(update) {
  alert('Got notification: ' + update);
});

答案 1 :(得分:0)

如果有人需要解决方案,请点击此处。事实证明,问题主要是由于等待for循环完成,因此术语中的每个项目都等待另一个函数完成。这就是我能够解决它的方式。它可能不是最佳的,但它现在可以做到:)

var friendsRef = firebase.database().ref('friendships/' + firebase.auth().currentUser.uid);

$scope.friends = $firebaseArray(friendsRef);

$scope.friendsinfo = [];

$scope.$watch('friends', function() {
    var newfriends = $scope.friends;

    asyncUpdateFriendsInfo(newfriends).then(function(newlist){
        $scope.friendsinfo = newlist;
    });
}, true);

function fetchPicture(ref){
    return ref.getDownloadURL().then(function(url) {
        return url;
    }).catch(function(error) {
        alert("error");
    });
}

function asyncUpdateFriendsInfo(newfriends){
    var deferred = $q.defer();
    var newfriendsinfo = [];

    for(var i = 0; i < newfriends.length; i++){
        var ref = firebase.database().ref('users/' + newfriends[i].$id);
        var profilePicRef = firebase.storage().ref("profilepictures/" + newfriends[i].$id + "/profilepicture");
        var picPromise = fetchPicture(profilePicRef);

        var newfriendid = newfriends[i].$id;
        var newfriendagreed = newfriends[i].agreed;

        picPromise.then(function(data){
            ref.once('value', function(snapshot){
                newfriendsinfo.push({
                    id: newfriendid,
                    name: snapshot.val().name,
                    email: snapshot.val().email,
                    agreed: newfriendagreed,
                    profilepicture: data
                });
            }).then(function(){
                if (newfriendsinfo.length == newfriends.length){
                    deferred.resolve(newfriendsinfo);
                }
            });
        });
    }

    return deferred.promise;
}