0

I am using a ng-repeat element to display a list of elements. Each element has some Parse.Pointer objects which are referencing other objects. In my template, when i want to display a value from a referenced object, the value only gets displayed when i first move to an other tab of my ionic app and then return to the tab where i want to display those values.

This is my call for the list of elements:

function getFragments(limit){
  var deferred = $q.defer();
  var query = new Parse.Query(Fragment);
  query.limit(limit);
  query.descending('createdAt');
  query.find({
    success: function(results){
        deferred.resolve(results);
    error: function(error){
        deferred.reject(error);
    }
  });
  return deferred.promise;
}

this is how i assign the values to the $scope:

Fragment.getFragments(20).then(function(fragments){
  $scope.fragments=fragments;
});

and this how i display a value of an object that has a pointer in the object (event is a pointer, name is a variable from the event object):

<ion-item ng-repeat="fragment in fragments">
    <h3>{{fragment.event.name}}</h3>

Each value of each object in the list also has a get property defined like this:

Fragment.prototype.__defineGetter__('event', function(){
  return this.get('event');
});

2 Answers 2

1

my first guess without actually running the code would be that angular doesn't know something was updated.

you need to tell Angular that something was updated and that it must run $digest or $apply to update it's scope too.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, using $scope.$apply() is a way to solve it. Thx! (I'll describe that solution in my answer)
0

After some struggling I found multiple solutions. I'll describe 2.

Solution 1

For each fragment in the array, fetch the Object for the pointer. On successfully retrieving the object call $scope.$apply() to notify the changes on the scope.

Fragment.getFragments(20).then(function(fragments){
  angular.forEach(fragments, function(fragment){
    if(fragment.event){
      promises.push(fragment.event.fetch({
        success: function(){
          $scope.$apply();
        }
      }));
    }
  });

But since I'm fetching multiple Objects from Pointers for each fragment i wanted to use promises and call $scope.$apply() when all promises are resolved.

    var promises = [];
    if(fragment.user){
      promises.push(fragment.user.fetch());
    }
    if(fragment.artist){
      promises.push(fragment.artist.fetch());
    }
    $q.all(promises).then($scope.$apply());

This gives me the message that $digest already is in progress so i guess that $q.all already starts the $digest. So just using $q.all(promise) solves the problem.

Solution 2

When querying for the fragments, fetch all the Objects for the Pointers before resolving the Promise.

function getFragments(limit) {
  var deferred = $q.defer();
  var query = new Parse.Query(Fragment);
  query.limit(limit);
  query.descending('createdAt');
  query.find({
    success: function (fragments) {
      var promises = [];
      angular.forEach(fragments, function(fragment){
        if(fragment.user){
          promises.push(fragment.user.fetch());
        }
        if(fragment.artist){
          promises.push(fragment.artist.fetch());
        }
      });
      $q.all(promises).then(function(){
        deferred.resolve(fragments);
      });
    },
    error: function (error) {
      console.log('log error');
    }
  });
  return deferred.promise;
}

Conclusion

In my opinion the 2nd solution is the best, because it is better to keep data logic out of the controller and don't use the $scope in the data logic.

Comments

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.