Timon
Timon

Reputation: 149

AngularJS scope undefined

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

Upvotes: 1

Views: 98

Answers (3)

georgeawg
georgeawg

Reputation: 48968

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

Upvotes: 1

strelok2010
strelok2010

Reputation: 1266

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;
})

Upvotes: 2

Odin
Odin

Reputation: 1001

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;
  });
 })
}

Upvotes: 0

Related Questions