Juan Diego
Juan Diego

Reputation: 1456

Injecting a service into a provider

I need to get a token which is saved on my controller in app.js, so I created a service

var app = angular.module('UnikaPage', ['LocalStorageModule','RutasModule','UploadModule']);
app.service('AuthService', function() {
        var kc = {};

        var setKeycloak = function(keycloak) {
            kc = keycloak;
        };

        var getKeycloak = function(){
            return kc;
        };

        return {
            setKeycloak: setKeycloak,
            getKeycloak: getKeycloak
        };

    });

My other module is UploadModule

var upload = angular.module('UploadModule', [ 'ngResource','flow','UnikaPage' ]).config(
        [ 'flowFactoryProvider', 'AuthService', function(flowFactoryProvider,AuthService) {
            AuthService.getKeycloak();
            flowFactoryProvider.defaults = {
                target : '/ng-flow-java/upload',
                permanentErrors : [ 500, 501 ],
                maxChunkRetries : 1,
                chunkRetryInterval : 5000,
                simultaneousUploads : 4,
                progressCallbacksInterval : 1,
                withCredentials : true,
                method : "octet"
            };
            flowFactoryProvider.on('catchAll', function(event) {
                console.log('catchAll', arguments);
            });
            // Can be used with different implementations of Flow.js
            // flowFactoryProvider.factory = fustyFlowFactory;
        } ]);

But I get AuthService is undefined, I tried without loading UploadModule in UnikaPage, I dont get errors but my UploadModule wont load.

Can I get a problem of circular dependencies on UnikaPage and UploadModule

Upvotes: 2

Views: 2210

Answers (2)

Mateus AJ Leon
Mateus AJ Leon

Reputation: 1382

You cannot call some things at config stage. For example, if you need to setup the Upload Module on config but, at the same time, you need to run the AuthService, you will not be able to do that, because this stage is to setup the services.

You can intercept the UploadModule AJAX ($http) calls with one $http interceptor, evaluate what you need to handle, and then let the request be made.

Here, on the Angular.js API Reference (supposing that you are using a version 1.2.x), you can see how to setup an interceptor, dealing with the requests on the fly: https://code.angularjs.org/1.2.28/docs/api/ng/service/$http#interceptors.

Also, another thing to keep in mind is that you need to provide a way to load and fill up the AuthService with its token and etc before the UploadModule dispatch something. If you need to identify some requestError that can occur, returning a 401 (Not Authorized), for example, you can setup an interceptor for that too, so you can call a login window, for example, to get the credentials of the user.

Edit 1:

I saw the code of ngFlow... You are using the flowInit directive to run, don't you? So you can pass to the directive flowInit an object scoped in your controller, for example, and extend the defaults that you've defined on config() stage. Following the original flow.js options, you can define a headers property, where you can define the headers for that situation.

<div flow-init="flowOptions">
    ...
</div>

On the controller:

angular.controller('Ctrl', ['$scope', function ($scope) {
    $scope.flowOptions = {
        headers: {
            'Authorization': 'token-here'
        }
    };
}]);

Edit 2 (Solution):

It ended up removing the defaults that were defined on config(), letting to controller define the entire flowInit options.

Looking over the source code of ngFlow its possible to see that they use the native angular.extend() which doesn't have recursive traversing inside the object. Read more here: http://docs.angularjs.org/api/ng/function/angular.extend

Upvotes: 2

Phil
Phil

Reputation: 164723

Remove the circular dependency. Move AuthService to its own module

angular.module('AuthModule', [])
    .factory('AuthService', function() {
        var kc = {};

        // etc
    });

Then add it to the UploadModule dependencies

angular.module('UploadModule', ['ngResource', 'flow', 'AuthModule'])

Upvotes: 1

Related Questions