Search code examples
angularjsangularjs-scope

Accessing returned scope method variables in another method in AngularJS


I have an Angular app with a service and a controller:

service.js

.factory('MyService', function ($http, $q) {
    var api_url = 'http://localhost/api/';

    var MyService = {

        list: function (items_url) {
            var defer = $q.defer();
            $http({method: 'GET', 
                url: api_url + items_url}).
                success(function (data, status, headers, config) {
                    defer.resolve(data);
                }).error(function (data, status, headers, config) {
                    defer.reject(status);
                });
            return defer.promise;
        },
        ...
   }
});

controller.js

.controller("ItemsCtrl", function ($scope, MyService) {

    $scope.getItems = function () {
        MyService.list('items/').then(function(data) {
            $scope.items = data;
        });
    };

    $scope.addItems = function () {
        $scope.getItems();

        // why is this undefined ??!!!
        console.log($scope.items); 
    };

The issue is that I want to call the $scope.getItems method inside the $scope.addItems method. Do I perhaps need to use $scope.apply(), as the returned value is a promise?

I think what I am displaying here is a general lack of understanding.


Solution

  • Change your controller like this:

    .controller("ItemsCtrl", function ($scope, MyService) {
    
        $scope.getItems = function () {
            return MyService.list('items/').then(function(data) {
                $scope.items = data;
            });
        };
    
        $scope.addItems = function () {
            $scope.getItems().then(function() {
    
              // should be what you want this time
              console.log($scope.items); 
    
            });
        };
    

    Your problem is when you call $scope.getItems(), http response is not returned yet, so $scope.items is not populated. You have to wait for all the promises are resolve to access items.