Search code examples
javascriptangularjsangularjs-http

Can't assign object returned by service to $scope


I'm trying to assign data returned by service to $scope property. Somehow it doesn't work properly. The service method correctly get data via $http.get but then it is not assigned to $scope in the controller.

app.service('StoreService', ['$http', function ($http) {

    this.getStoreNamesService = function () {
        console.log('getStoreNames called');
        $http.get('http://localhost:8080/storys')
            .success(function (response, status) {
                console.log(response);
                return response;
            })
    };
}]);

app.controller('ItemFormController', ['$scope', '$http', '$mdDialog', 'itemService', 'StoreService', function ($scope, $http, $mdDialog, itemService, StoreService) {

    $scope.storeNames = StoreService.getStoreNamesService();
}]);

Printing the response in service gives correct data. But when I'm printing $scope.storeNames it gives me undefined also on the views there is no data.

app.js:

var app = angular.module('BlankApp', ['ngMaterial', 'ngRoute'])
.config(function($mdThemingProvider) {
    $mdThemingProvider.theme('default')
        .primaryPalette('teal')
        .accentPalette('red')
        .warnPalette('red');
});

app.config(function ($routeProvider) {
    $routeProvider
        .when('/addItem', {
            templateUrl: 'templates/addItemForm.html',
            controller: 'ItemFormController'
        })
        .when('/', {
        templateUrl: 'templates/first.html'
        })
        .when('/store', {
            templateUrl: 'templates/itemsInStore.html',
            controller: 'StoreController'
        })
        .when('/item/:itemId', {
            templateUrl: 'templates/itemView.html',
            controller: 'ItemController'
        })
        .otherwise({
            template: '<h1>otherwise template</h1>'
        })
});

The order of script tags:

    <!-- Angular Material requires Angular.js Libraries -->
<script src="js/angular-1.5.8/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-route.min.js"></script>

<!-- Angular Material Library -->
<script src="js/AngularMaterial/angular-material.js"></script>

<!-- Your application bootstrap  -->


<script src="js/app.js"></script>
<script src="js/service/itemService.js"></script>
<script src="js/service/StoreService.js"></script>
<script src="js/controller/testController.js"></script>
<script src="js/controller/SideNavController.js"></script>
<script src="js/controller/ItemFormController.js"></script>

<script src="js/controller/sampleController.js"></script>
<script src="js/controller/ItemController.js"></script>

Solution

  • This should work:

    app.service('StoreService', ['$http', function ($http) {
    
    this.getStoreNamesService = function () {
        console.log('getStoreNames called');
        return $http.get('http://localhost:8080/storys').then(
            function success(response, status) {
                console.log(response);
                return response;
            })
        };
    }]);
    
    app.controller('ItemFormController', ['$scope', '$http', '$mdDialog', 'itemService', 'StoreService', function ($scope, $http, $mdDialog, itemService, StoreService) {
        StoreService.getStoreNamesService().then(function(result){
            $scope.storeNames = result;
        });
    }]);
    

    You can only assign the variable storeNames after the promise is resolved. The way you were doing, the promise was being assigned to the variable.

    Also notice that .success() is deprecated. Use .then() instead.