20

I've created a service which checks the user login state (log the user in if token exists, otherwise redirect to login page).

Originally I called this service through the routeProvider resolve - this works perfectly once, but since Angularjs services are singleton the test would not run for consecutive calls.

I then tried to move the test into a method within the returned object, but I can't seem to be bale to get the routeProvider resolve to call a specific method of a service (which makes sense in a way).

Question is, how do I make sure my test is executed each time the route is loaded?

In the egghead videos series (http://www.egghead.io/video/rbqRJQZBF3Q) he uses a function assigned to the controller but this doesn't seem like the right solution for a production app (I don't want to assign a function to a specific controller and I do believe the Angularjs dependency injection won't work).

shauneba
  • 2,122
  • 2
  • 22
  • 32
Guy Nesher
  • 1,385
  • 2
  • 14
  • 26

2 Answers2

27

service are singletons means there are initialized only one but time but if you simply return from service it will be called one time but if you return a function from service it will be called again and again .See Below Sample for working

var app = angular.module('ajay.singhApp', [])
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider
      .when('/view1', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl',
        resolve: {
            myVar: function (repoService) {
                return repoService.getItems().then(function (response) {
                    return response.data;
                });
            }
        }
      })
        .when('/view2', {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl'
        })
      .otherwise({
        redirectTo: '/view1'
      });
  }]);


app.factory('repoService', function ($http) {
    return {
        getItems: function () {
            return $http.get('TextFile.txt');
        }
    };
});
Ajay Beniwal
  • 18,857
  • 9
  • 81
  • 99
  • 1
    Thanks, That works. though it still feels like a work around. Was expecting a more straightforward solution :( – Guy Nesher May 23 '13 at 14:16
  • 2
    how do I use returned response.data ? – John Smith Mar 14 '14 at 20:33
  • 2
    In your controller, in this case MainCtrl, inject $route as dependency and $route.current.locals.myVar will contain the data. – ghiden Mar 19 '14 at 22:53
  • Even better, if you inject 'data' as its dependency to your controller, it will be the data that gets resolved. – ghiden Mar 19 '14 at 23:03
  • 8
    Is this code going to work when minified? As far as I understand `myVar: function(repoService)` will stop working once minified and to solve this problem you need to explicitly handle injection of repoService. Or I am wrong? – Kirill G. Apr 09 '14 at 05:23
  • How to get `myVar` in controller? – Ahmed Oct 02 '15 at 20:44
1

Adding to @Ajay's response, you can use a string rather than a standard property name, which will help with minification:

resolve: {
    'myVar': function (repoService) {
        return repoService.getItems().then(function (response) {
            return response.data;
        });
    }
}
panesofglass
  • 267
  • 3
  • 10
  • 2
    What about arguments injection array notation? The minification will break the sample code the rename of function the minifer will do? Of course i can use $inject but this is not easy... – Konstantin Isaev Jun 18 '14 at 00:17