1

I know I can't dependency inject a factory into a config as they only take providers, which as I understand it are just a fully customizeable services that factories and services inherit. So I thought I'd try creating a bunch of small route providers so I didn't have to add commonly reused resolve actions as anonymous functions in variables within the config, which just gets messy after awhile.

Provider

angular.module('project.app.service', [])

    .provider('UserAuthService', function () {

        this.$get = ['UserResource', function (UserResource) {

            return {
                getUser: getUser
            };

            function getUser() {
                 return UserResource.auth().$promise;
            }
        }];
    }),
...

Routes Including Provider Module

angular.module('project.app.route', ['project.app.service'])

.config(['$stateProvider', '$urlRouterProvider', 'UserAuthServiceProvider', 
    function ($stateProvider, $urlRouterProvider, UserAuthServiceProvider) { 

        $stateProvider

            ...

            .state('dashboard.index', {
                url: "/map",
                templateUrl: "templates/dashboard/map/map.html",
                controller: 'MapController',
                controllerAs: 'mapCtrl',
                resolve: {
                    UserAuth: UserAuthServiceProvider.getUser()
                }
            })
            ...
});

The docs state that only the $get function can be injected, but it throws this error even though it appears like it should work:

TypeError: UserAuthService.getUser is not a function

This seems like it should work from the docs and examples, and with credit to the comments below for providing help and brainstorming the issue.

Is there a single line resolve parameter solution to make this more modular, or should I just drop anonymous functions at the top of the ui-route config, that inject a factory, and forget about this?

Claies
  • 22,124
  • 4
  • 53
  • 77
mtpultz
  • 17,267
  • 22
  • 122
  • 201
  • Looks like you made a mistake with module naming. parkable.app.service should be project.app.service or the other way around. – cabey Jun 30 '15 at 00:38
  • Hi @cabey77, actually that was a mistake when entering the code into stackoverflow – mtpultz Jun 30 '15 at 00:40
  • Oh okay, well looks like this will help, http://stackoverflow.com/questions/19966013/angularjs-inject-provider-to-module-config. Something about needing .provider in the name. – cabey Jun 30 '15 at 00:44
  • Hi @cabey77, I'm not sure I understand it appears to be the same kind of implementation, but I'm already prefixing the provider with Provider having read the docs. Is there something else I should be looking at in that post? – mtpultz Jun 30 '15 at 00:53
  • Oh, I apologize, I thought the post was saying you needed .providerProvider, but i guess it's just the Provider suffix. – cabey Jun 30 '15 at 00:58
  • 1
    Oh wait now I see, you need the provider suffix when you inject. So it's UserAuthProviderProvider – cabey Jun 30 '15 at 00:59
  • Hi @cabey77, so if I named my .provider('UserAuth', ...) then injected in config as 'UserAuthProvider'? – mtpultz Jun 30 '15 at 01:04
  • Yeah try it out and let me know. – cabey Jun 30 '15 at 01:05
  • I'm kind of stuck on this. It should be working. All I can see is a missing semi-colon after return UserResource.auth().$promise – cabey Jun 30 '15 at 02:14
  • Hi @cabey77, thanks for the help. Yah, I'm definitely stuck. I looks like the other examples. I guess I'm stuck using anonymous functions in the config and just using a factory unless someone can pull this off :) Thanks again for the help. – mtpultz Jun 30 '15 at 03:29

1 Answers1

2
  1. You are only supposed to use Providers to configure your services while your application is configuring/initializing (during module.config) with anything it needs prior to being created. You should not use it anywhere else.
  2. If there's nothing to configure on your provider (you supply nothing but $get, which is used by Angular to actually create the singleton when it's needed at runtime), then there's no reason to inject it into .config (and you also just simplify by using module.factory instead of module.provider).
  3. UI-Router will resolve dependencies required by any items in a state's resolve. When the resolve item is a function, it'll try to resolve any dependencies in that function by param name (known as implicit annotation). Or you can use the inline array annotation.

Example (using implicit annotation)

 angular.module('project.app.route', ['project.app.service'])
    .config(['$stateProvider', '$urlRouterProvider', 'UserAuthServiceProvider', 
        function ($stateProvider, $urlRouterProvider, UserAuthServiceProvider) {
            // configure your UserAuthServiceProvider, if there is anything.

            $stateProvider
                .state('dashboard.index', {
                    url: "/map",
                    templateUrl: "templates/dashboard/map/map.html",
                    controller: 'MapController',
                    controllerAs: 'mapCtrl',
                    resolve: {
                        UserAuth: function(UserAuthService) { return UserAuthService.getUser(); }
                    }
                });
    });

Example (using inline array annotation)

 angular.module('project.app.route', ['project.app.service'])
    .config(['$stateProvider', '$urlRouterProvider', 'UserAuthServiceProvider', 
        function ($stateProvider, $urlRouterProvider, UserAuthServiceProvider) {
            // configure your UserAuthServiceProvider, if there is anything.

            $stateProvider
                .state('dashboard.index', {
                    url: "/map",
                    templateUrl: "templates/dashboard/map/map.html",
                    controller: 'MapController',
                    controllerAs: 'mapCtrl',
                    resolve: {
                        UserAuth: ['UserAuthService', function(UserAuthService) { return UserAuthService.getUser(); }]
                    }
                });
    });

Which should you use, implicit or inline array annotation? Well, it depends on how your project is built. If your source is not minified (it should be, for production builds) or you have some module in your build pipeline that automatically converts implicit to inline array annotations, use implicit. Otherwise, use inline array.

moribvndvs
  • 42,191
  • 11
  • 135
  • 149