5

I'm confused as to why I cannot get this service call to perform as needed. The console.log's within definitionsService.get promise resolution are what I would expect (the object I'm aiming to return). However the console.log right before I return defs is undefined which, of course, means my returned value is undefined. What am I missing?

function getDefinitions() {
  var defs;
  definitionsService.get().$promise.then(function(data) {
    console.log(data);
    defs = data;
    console.log(defs);
  });
  console.log(defs);
  return defs;
};

I changed the above to:

function getDefinitions() {
  var defs = $q.defer();
  definitionsService.get().$promise.then(function(data) {
    defs.resovle(data);
  });
  return defs.promise;
};

per the below answer.

I also changed the way I call this method per the same answer like this:

function detail(account) {
  getDefinitions().then(function(definitions) {
    var key = angular.isDefined(definitions.ABC[account.code]) ? account.code : '-';
    return definitions.ABC[key].detail;
  });
}

Then in my controller I'm trying to do the following:

var getAccounts = function() {
  playersService.getAccounts({
    playerId: playerId
  }).$promise.then(function(accounts) {
    for (var i = 0; i < accounts.length; i++) {
      accounts[i].detail = utilitiesService.detail(accounts[i]);
    }
    vm.accounts = accounts;
  });
};

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

init();

My problem is that accounts[i].detail is consistently undefined.

2 Answers 2

2

Welcome to the world of asynchronous calls.

If you are making an async call inside getDefinitions (from definitonsService), then you must assume getDefinitions() is async as well. Which means you cannot simply return defs.

When you print defs before returning it, the async call of the service has yet to have been carried out.

defs should also be a promise object. You can then return it as you do, but the method invoking it should also use it with .then(function(defs)...

Or in code form:

function getDefinitions() {
  var defs = $q.defer();
  definitionsService.get().$promise.then(function(data) {
    defs.resovle(data);
  });
  return defs.promise;
};

And whoever calls getDefinitions() :

getDefinitions().then(function(defs) {
 // do something with defs...
}

Answer to question after edit:

The problem is once again with the async nature inside the getAccounts method. utilitiesService.detail is an async method. So you are in fact assigning promises, not values, to accounts[i].detail.

Since each account will entail an async call, using $q.all seems like a good idea:

var promises = [];
for (var i = 0; i < accounts.length; i++) {
      promises.push(utilitiesService.detail(accounts[i]));
    }
$q.all(promises).then(function(values)){
 // you should have all the account details inside 'values' and can update vm.accounts
}

remember - getting the promise is synchronous. Getting the value that the promise... well, promises to get you - that's asynchronous.

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

7 Comments

That was very helpful. My only remaining problem is that when I call the method which calls getDefinitions from my controller it also seems to be returning a promise.
Well, the asynchronous nature will trickle down throughout the entire call stack. Can you provide additional code for clarity?
Added details to my original question.
Added details to my original answer :)
...and that block of code should go inside }).$promise.then(function(accounts) {?
|
0

The problem is that you are returning defs before the promise has resolved, while defs === None.

You can solve this by changing your code a bit:

function getDefinitions() {
  return definitionsService.get().$promise.then(function(data) {
    return data;
  });
};

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.