0

So, I'm trying to dynamically load a file that adds a controller to my main module. The thing is that I don't want to reference the file itself in a script tag.

To be more specific, I have 2 controller files. The main controller file mainController.js referenced in my index.html file. Any controller that I add to that file loads without issues.

The controller file I want to use for my login page login.js, contains the following information:

function LoginCtrl($http){
  console.log("Controller loaded");  
};

angular
    .module('inspinia')
    .controller('LoginCtrl', LoginCtrl);

All my controller files are in the same folder, however, contrary to the mainController.js, the login.js file does not appear inside any .html file.

My intention was to load the login.js file dynamically inside my stateProvider like this:

$stateProvider
...
.state('logins', {
            url: "/logins",
            templateUrl: "views/login.html",
            controller: LoginCtrl,
            data: { pageTitle: 'Login', specialClass: 'gray-bg' },
            resolve: {

                loadPlugin: function($ocLazyLoad) {
                    return $ocLazyLoad.load ({
                    name: 'inspinia.LoginCtrl',
                      files: ['js/controllers/login.js']
                    });
                }
            }
        })
...

So long as I dont try to dynamically load the login.js file (so adding a reference to the file in a .html file or adding the login controller code inside the mainController.js file) everything works. But as soon as I try to remove the references to force the stateProvider to take care of the loading I get an Error: $injector:modulerr

Anyone knows what's the proper way to call the lazyLoader so I can only load my .js files when I need them?

EDIT info: Something that I forgot to mention: The file-loading part itself seems to be working. If I do not call the controller anywhere and only load it. I can see the controller file being loaded by the browser. But the problem seems to be a timing issue. If I mention the controller name inside the .state() angular tries to access it before it gets loaded and the whole thing crashes before even loading the file

Axel
  • 414
  • 1
  • 7
  • 21

1 Answers1

0

I recomend you to look over the ocLazyLoad to see how a controller is declared and loaded with ui-router resolve state property:

https://oclazyload.readme.io/docs/with-your-router

Basically, I think that what is missing in your approach is to use the string controller declaration, not the function one:

$stateProvider
...
.state('logins', {
        url: '/logins',
        templateUrl: 'views/login.html',
        controller: 'LoginCtrl as login',
        data: {
            pageTitle: 'Login',
            specialClass: 'gray-bg'
        },
        resolve: {
            loadPlugin: function($ocLazyLoad) {
                return $ocLazyLoad.load('js/controllers/login.js');
            }
        }
    })
...

A tip that is important to use is: simplify the first implementation of something that you didn't used before. Your example shows a lot of parameters on the ocLazyLoad service. Try to load first the main element that you need, progressively adding one after the other after it succeeds because, sometimes, you may be on the right track and something like this, which you're unaware of, can lead you to a loooooong debug routine.

Also, take a look at the example below:

https://github.com/ocombe/ocLazyLoad/tree/master/examples/complexExample

It has a state declaration very similar to yours. Compare each other and modify to suit your needs.

Mateus Leon
  • 1,381
  • 1
  • 14
  • 21