0

I have the following setup in my controller which I would expect to update my view appropriately, but it does not until I refresh the page:

var vm = this;
var loadingGames = $q.defer();

var getGames = function() {
  playersService.getGames({
    playerId: playerId
  }).$promise.then(function(data) {
    vm.games = data;
    loadingGames.resolve();
  });
};

var init = function() {
  getGames();
}

init();

var updateSchedule = function() {
  getGames();
  loadingGames.promise.then(function() {
    populateOptions(vm.games);
    vm.tableParams.reload();
  });
};

vm.performAction = function(action, gameId, gameType) {
  utilitiesService.performOperation(action, gameId, gameType).then(
    function() {
      updateSchedule();
    },
    function(httpError) {
      alert('Couldn\'t '+ action +' game: ' + httpError);
    });
};

var populateOptions = function(games) {
  angular.forEach(games, function(game) {
    game.options = getOptions(game);
  });
};

When I click the performAction button in my UI I expect to see updated vm.games in my view. However, I always need to refresh the page to see the changes. I know this is most likely related to $scope.$apply but I'm not grasping it at the moment.

16
  • 1
    Are you sure that populateOptions and vm.tableParams.reload() are synchronous? Commented Aug 12, 2015 at 22:40
  • How do you bind games in your view? When you set vm to this, is this refer to controller? Commented Aug 12, 2015 at 22:46
  • @Franck, yes this refers to the controller. I use controllerAs syntax. Commented Aug 12, 2015 at 22:46
  • Does getOptions return a promise? Is it an angular promise? Commented Aug 12, 2015 at 22:48
  • So your view bind to games not vm.games, right? Commented Aug 12, 2015 at 22:50

1 Answer 1

2

The error is your loadingGames variable. You instantiate it only once and try to resolve it many times. When you call it first from your init function, you resolve it. As a result, all the subsequent calls to getGames which are relaying on loadingGames do NOT wait because the promise is already resolved. They are therefore using the old vm.games.

To solve this problem, simply return the promise from your playerService. You can chain promise, meaning that by letting the actual then and returning the promise from your service, the vm.games = data will be executed before the code in the next then. Therefore, you will call getGames.then(...) from your other functions.

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

2 Comments

Unfortunately I'm running into a Cannot read property 'then' of undefined error when using this structure: var updateSchedule = function() { getGames().then(function() { populateOptions(vm.games); vm.tableParams.reload(); }); };
You need to be returning a promise from your getGames. So return PlayerService.getGames({playerId:playerId}).$promise

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.