Rohìt Jíndal
Rohìt Jíndal

Reputation: 27202

AngularJS : access scope object from parent to child

Query : Want to access the Main Controller scope object into ui-view states.

Problem Statement :

Here, I am creating one scope object($scope.myVar) based on the response getting from the API that will be applicable across the application. hence, I wrote an API in Main Controller to create this scope object as it is a parent controller and all other states(ui-view) are child.

[1]: https://i.sstatic.net/Fr4zK.png Here, I want to access that $scope.myVar in all the states in ui-view.

Tried so far : HTML

<body ng-controller="MainController">
  <div class="className">
    <ui-view></ui-view>
  </div>
</body>

Main Controller

app.controller('MainController', function($scope, $http) {

$http({
  method: 'GET',
  url: '/someUrl'
  }).then(function successCallback(response) {
    $scope.myVar = 'xyz'; // This variable i want to access into the state controller.
  }, function errorCallback(response) {        
  });
});

State controller :

app.controller('StateController', function($scope, $timeout) {

  console.log($scope.myVar); // undefined (Not working)

  $timeout(function() {
    console.log($scope.myVar); // xyz (working)
  }, 500);
});

I want to access $scope.myVar without using $timeout service. What is the correct way to do this ?

Upvotes: 2

Views: 1626

Answers (2)

S B
S B

Reputation: 1363

You can use angular $q service

Using promises and $q to handle asynchronous calls

var app = angular.module("MY_APP", []);
//Parent Controller
app.controller("MyCtrl1", [
    '$scope','$q','$timeout', function($scope,$q,$timeout) {

 $scope.async = function(name) {
  var deferred = $q.defer();
  //Async call: Use your ajax call here instead of $timeout
  /*
  $http.get('/someUrl')
       .success(function(data) { 
          $scope.myVar = 'xyz';
          deferred.resolve(data);
       }).error(function(msg, code) {
          deferred.reject(msg);
          $log.error(msg, code);
       });
  */
  $timeout(function() {
    deferred.notify('About to greet ' + name + '.');
     if (name) {
      deferred.resolve('Hello, ' + name + '!');
     } else {
      deferred.reject('Greeting ' + name + ' is not allowed.');
     }
   }, 1000);
  return deferred.promise;
}
}]);
//Child Controller
app.controller("MyCtrl2", [
    '$scope','$q', function($scope,$q) {
 // call parent async method
var promise = $scope.$parent.async('Sai');
promise.then(function(greeting) {
//check your variable here
/*
console.log($scope.$parent.myVar); 
*/
  alert('Success: ' + greeting);
}, function(reason) {
  alert('Failed: ' + reason);
}, function(update) {
  alert('Got notification: ' + update);
});

}]);

Fiddle example

Upvotes: 1

Pengyy
Pengyy

Reputation: 38171

you can use $parent.myVar to access data of parentScope

For your situation(async call), you can add $scope.$watch to watch the parent scope variable.

$scope.$watch("$parent.myVar", function(newValue, oldValue) {
  $scope.data = newValue;
)

Here you want to get data immediately when child state initializing, you can try with resolve.

$stateProvider.state({
  name: 'hello',
  url: '/hello',
  templateUrl: '...',
  resolve: {
    testData: function($http) {
      // invoke your async call here again
    }
  }
})

here are some issues about resolve which may help.

Upvotes: 1

Related Questions