1

In my ControllerA i have an init() function which loads these services:

init(){
childrenDataService.getData($scope.family_id).then(function(result) {
  $scope.childrenName = result;
  $scope.selectedChild = result[0];
})

console.log($scope);
console.log($scope.selectedChild)

//this doesn't work => TypeError: Cannot read property 'id' of undefined
//can't access $scope.selectedChild.id
additonalDataService.getData($scope.selectedChild.id).then(function(result){
  scope.additional = result;
})
}

The loading of ChildrenDataService is working fine. My Problem is that console.log($scope) gives me the full object. The attribute $scope.selectedChild is filled with an object.

But when I try to access this directly through console.log($scope.selectedChild) i get 'undefined'.

Why can't I access this directly? I need to access this because additonalDataService depends on the default selection of childrenDataService.

Thanks for your help

0

3 Answers 3

2

In your case, when you try get $scope.selectedChild.id it's really undefined, because childrenDataService.getData doesn't completed. You can try fix this with:

init(){
childrenDataService.getData($scope.family_id).then(function(result) {
  $scope.childrenName = result;
  $scope.selectedChild = result[0];
  additonalDataService.getData($scope.selectedChild.id).then(function(result){
      $scope.additional = result;
  })
})

}

Update

If your services return promises, you can use promise-chaining:

childrenDataService.getData($scope.family_id).then(function(result) {
  $scope.childrenName = result;
  $scope.selectedChild = result[0];
  return additonalDataService.getData(id);
})
.then(function(result){
  $scope.additional = result;
})
Sign up to request clarification or add additional context in comments.

3 Comments

I tried this and it works, but the additonalDataService is depending on multiple variables. I shortend the example for here. Isnt there a more nice solution than to stage all the services in each other?
you can store all the promises in an array and use $q.all to execute code when all the promises are resolved
"you can store all the promises in an array and use $q.all to execute code when all the promises are resolved" - but he need result of first resolved promise to create second promise, how it will works?
1

Isnt there a more nice solution than to stage all the services in each other?

You can use promise chaining.

var initPromise = init(){
    //return derived promise
    return (
        childrenDataService.getData($scope.family_id)
            .then(function(result) {
                $scope.childrenName = result;
                $scope.selectedChild = result[0];
                //return for chaining
                return ($scope.selectedChild);
             })
        ;
    );
};

Chain from the returned promise.

initPromise.then(function (selectedChild) {
    additonalDataService.getData(selectedChild.id)
        .then(function(result){
             scope.additional = result;
        })
    ;
});

Because calling the .then method of a promise returns a new derived promise, it is easily possible to create a chain of promises. It is possible to create chains of any length and since a promise can be resolved with another promise (which will defer its resolution further), it is possible to pause/defer resolution of the promises at any point in the chain. This makes it possible to implement powerful APIs.1

Comments

0

The problem you are facing is the callback function. the callback which means call me back later it gives result after everything is done processing.

Try and put everything within the callback function

Try this, it might help

init(){
childrenDataService.getData($scope.family_id).then(function(result) {
 $scope.childrenName = result;
 $scope.selectedChild = result[0];

console.log($scope);
console.log($scope.selectedChild)

//this doesn't work => TypeError: Cannot read property 'id' of undefined
//can't access $scope.selectedChild.id
additonalDataService.getData($scope.selectedChild.id).then(function(result){
  scope.additional = result;
  });
 })
}

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.