DeejC
DeejC

Reputation: 179

AngularJs upgrade Unknown Provider after bootstrapping change

I am attempting to upgrade a large angular.js app (1.5.9) to the latest version of Angular.

I am in the process of turning the app into a hybrid AngularJs/Angular app and have reached this step in the guide:

https://angular.io/guide/upgrade#bootstrapping-hybrid-applications

So far I have changed from using gulp to webpack 4 and the app is working the same as before.

The issue I am having is, when I switch from using the ng-app directive in my index.html to bootstrapping in Javascript the app fails to start, throwing this error:

Uncaught Error: [$injector:unpr] Unknown provider: StateServiceProvider <- StateService

This is coming from my app.js file which looks like this:

angular.module('app-engine', [
    'app-engine.state',
    'app-engine.api',
    // other modules
])
.factory('bestInterceptor', bestInterceptor)
// other configs which aren't throwing Unknown provider errors
.run(startUp);

bestInterceptor.$inject = ['StateBootstrappingService'];

function bestInterceptor(StateBootstrappingService) {
    return {
        request: config => {
            if (!StateBootstrappingService.isBestSsoOn()) {
                config.headers['x-impersonated-user'] = StateBootstrappingService.getUserName();
            }
            return config;
        }
    };
}

startUp.$inject = ['$rootScope', '$state', '$timeout', 'StateService']

function startUp($rootScope, $state, $timeout, StateService) {
    // start up code
}

There is a separate app.modules.js file, which defines the other modules in the app.

Including:

angular.module('app-engine.state', ['rx', 'app-engine.api']);

The service which is mentioned in the Unknown provider error looks like this:

(function() {
    'use strict';
    angular
        .module('app-engine.state')
        .factory('StateService', StateService);

    StateService.$inject = [
        '$state',
        '$log',
        'rx',
        // a few other services that exist in the app
    ];

    function StateService(
         // all the above in $inject
    ) {
         // service code
    }
})();

As the guide instructs, I am removing the ng-app="app-engine" from my index.html and adding it into the JavaScript instead. I've added it at the bottom on my app.modules.js file.

angular.bootstrap(document.body, ['app-engine']);

After this change is when the Unknown provider error is thrown. I have confirmed the source is my startUp function in app.js. I have tried including all the modules in the app in the 'app-engine' requires array, which did not change anything. It's interesting that the bestInterceptor function is not throwing any errors, despite also using a service (The StateBootstrappingService is being set up in the same way as the StateService).

Is there anything obvious I am doing wrong? Or anyone have any ideas how to solve this?

Upvotes: 1

Views: 323

Answers (1)

everythingEzra2
everythingEzra2

Reputation: 163

Try this:

angular.element(document).ready(function () {
  angular.bootstrap(document.body, ['app-engine'])
})

For me this was necessary because the other sub components (providers and services) had not yet been added to the module yet. Running the it on "document.ready()" gives those items an opportunity to attach before trying to manually bootstrap (because they cannot be added later when manually bootstrapping)

I don't love the use of document.ready() so I'm still looking for a more offical way to do this

Upvotes: 0

Related Questions