Search code examples
javascriptangularjsangularjs-service

Force AngularJS service to return data before loading controller


I have a service in Angular which uses my API to get user information and provides it to my controllers. It's set up like this:

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
  .service('userInfo', function($http, $cookies){
    $http.get('/api/users/' + $cookies.id).
    success(function(data) {
      var userInfo = data.user[0];

      return userInfo;
    });
  }). // other stuff comes after this

In my controllers, I include it like:

function userProfile($scope, $cookies, userInfo, $http, $resource, $routeParams, $rootScope){
    $scope.user = userInfo;
    console.log('user info is')
    console.log(userInfo);

This is returning no data, while if I put the same service function in the controller itself it returns just fine. What am I missing here? Never used DI/Services in Angular before so might be a simple mistake somewhere.

I need to ensure that the service returns data before the controller loads. How can this be accomplished


Solution

  • You can make the factory to return a promise like this:

    angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
        .service('userInfo', function ($http, $cookies) {
        var promise = $http.get('/api/users/' + $cookies.id).
        success(function (data) {
            var userInfo = data.user[0];
            return userInfo;
        });
        return promise;
    }) // other stuff comes after this
    

    And in your controller, do

    function userProfile($scope, $cookies, userInfo, $http, $resource, $routeParams, $rootScope){
        userInfo.then(function(data){
            $scope.user = data;
        });
    }
    

    This can guarantee that whenever you use the service, it always gives you the data synchronously, you don't have to necessarily load any data before loading the controller.