3

Let's say I have a site where every controller is going to rely on a 'User' object. So I create a user service for the controllers to use to get this data:

myApp.factory('UserService', function ($http) {
    var user = { Id: 1, Name: 'Test' }; 
    return {
        User: user
    };
});

Where my controllers then look like this:

myApp.controller('SearchController', function ($scope, UserService) {
    $scope.User = UserService.User;
})

My question is, assuming now we need to pull in that data from a $http call (where the returned data is then manipulated before handing off to the controllers) AND just about every controller is going to need this data (so having them each manipulate it doesn't make sense), how do I go about implementing this?

I'm going in circles with examples regarding promises so I'm confused as to the proper way of handling this. Ideally I just need a way to have this data resolved before any controllers/views are populated

John
  • 17,163
  • 16
  • 65
  • 83

2 Answers2

1

I would avoid having a service doing something like this since it is generally bad form to have a service holding a state (this is up for debate Should an Angular service have state?)

I worked around this in my most recent app by creating a function on the rootscope that gets the user, and call that function whenever I need to know the user.

Community
  • 1
  • 1
Mindstormy
  • 490
  • 4
  • 14
0

My main hangup was the processing after receiving the data, which I was able to handle by wrapping up the $http promise like so:

myApp.factory('UserService', function ($http, $q) {
    var dfrd = $q.defer();

    $http({ method: 'GET', url: '/api/User' }).success(function (data, status, headers, config) {
        dfrd.resolve({
            Name: data.UserName,
            /*More custom properties */
        });
    });

    return {
        getUser: function () { return dfrd.promise; }
    };
});

myApp.controller('SearchController', function ($scope, $location, UserService) {
    UserService.getUser().then(function (data) {
        $scope.User = data;
    });
}
John
  • 17,163
  • 16
  • 65
  • 83
  • You should not do this. Instead you should use a resolver pattern. ui-router has it built in. basically, it works like this. you create a resolver that resolves all the promises you need to and it will not instantiate the controller until every single promise you need resolved is resolved. the resolver service then is injected into your controller, and instead of being references to promises, it is a reference to your fully resolved objects. check out this great article by John Papa https://johnpapa.net/route-resolve-and-controller-activate-in-angularjs/ *bonus it makes testing way easier* – Doug Chamberlain Aug 09 '16 at 09:50