6

I'm all new to AngularJS and need some help, I have a "AppCtrl" and from there I have a HTTP webservice call - and need the webservice call response accessible in my other controllers.

angular.module('starter.controllers', [])

.controller('AppCtrl', function($scope, $http) {

    $scope.webservice_url = "http://webserviceurl.com/";

    $http.get($scope.webservice_url+"?action=get_settings").success(function(data, status, headers, config) {
        $scope.stations = data.stations;
    });
})

This works FINE - and i can access the $scope.stations in my templates - BUT now i want to access the $scope.stations in my "PlaylistCtrl" controller, but this is undefined :(

.controller('PlaylistCtrl', function($scope, $stateParams) {
    console.log($scope.stations); // is undefined :(
})

How can I make sure the http call is "done" (success) before the "PlaylistCtrl" is loaded ...

pkdkk
  • 3,905
  • 8
  • 44
  • 69

4 Answers4

10

you should turn the http into service/factory if possible

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, dataService) {
  dataService.then(function (data) {
    $scope.data = data
  })
});


app.controller('SecondCtrl', function($scope, dataService) {
  dataService.then(function (data) {
    $scope.secData = data
  })
});

app.service('dataService', function ($http, $q){
  var defferer = $q.defer()

  $http.jsonp('http://ip.jsontest.com/?callback=JSON_CALLBACK').success(function (data){
    defferer.resolve(data)
  })

  return defferer.promise
})

http://plnkr.co/edit/8k97DngZ8KoFOBPFJG82?p=preview working example

maurycy
  • 8,455
  • 1
  • 27
  • 44
2

$scope.stations ist not undefined in PlayListCtrl because the HTTP call has not finished, but because PlayListCtrl has a different $scope than AppCtrl.

You should put the webservice call into a service and inject that service into all controllers that require it.

Jens Neubauer
  • 1,090
  • 1
  • 13
  • 24
  • Thanks, that make sense - But I don't know how to make a service and how to inject it - Do you have an example an so ? ;) – pkdkk Jun 19 '14 at 08:50
1

In Angular, you don't wait for data before rendering. You let it render, even if the array is empty initially, and then once the data returns, you render again. Angular does this to maintain a high level of responsiveness. It is by design, and not something you should try to change.

All you need to do to fix your undefined variable is initialize the stations scope variable in your controller. Although it gets overwritten when the data returns from your service, it doesn't matter because angular will watch for changes to the scope variable by reference and update all views when it does.

angular.module('starter.controllers', [])

.controller('AppCtrl', function($scope, $http) {

    $scope.webservice_url = "http://webserviceurl.com/";

    $scope.stations = [];
    $http.get($scope.webservice_url+"?action=get_settings").success(function(data, status, headers, config) {

        $scope.stations = data.stations;
    });
})

In your inner controller, if the data hasn't returned yet, $scope.stations will be an empty array:

.controller('PlaylistCtrl', function($scope, $stateParams) {
    console.log($scope.stations); // is []
    $scope.$watch('stations', function(newVal) {
        alert('data returned!! updating views!');

    });
})

Once the data returns, the array reference on the scope is overwritten, any $watch handlers are called to update the view.

Michael Kang
  • 52,003
  • 16
  • 103
  • 135
-4
// Make a remote request.
$http.get('some wonderful URL for a service').success(function (results) {
  superImportantInfo = results;

  semaphore = true;
});

while (!semaphore) {
  // We're just waiting.
}

This is how you can let your controller to wait till it finishes execution of controller 1 and before moving to the next controller.

Hope this help!

Lalit Sachdeva
  • 6,469
  • 2
  • 19
  • 25