0

I'm trying to use require.js to lazy load some of my dependencies in angular, and I'm having a few issues.

I believe the following code should try to load the register controller before angular neeeds it (via angular-ui-router):

  .state('register', {
    url: '/register',
    class: 'login',
    title: 'Register',
    templateUrl: 'app/security/register.view.html',
    controller: 'RegisterController',
    controllerAs: 'register',
    resolve: {
      require: function ($q) {
        return $q(function (resolve, reject) {
          console.log('security/register.controller loading')
          require(['security/register.controller'], function () {
            console.log('security/register.controller loaded')
            resolve()
          })
        })
      }
    }
  })

But when I switch from the login state to the register state, I get the following output in the console:

RouteChanged Login
security/register.controller loading
security/register.controller loaded
RouteChanged Register
Error: [ng:areq] http://errors.angularjs.org/1.5.8/ng/areq?p0=RegisterController&p1=not%20aNaNunction%2C%20got%20undefined

So even though the resolve runs, angular throws an error saying it can't find the RegisterController.


Here's a link to a plunker. As you can see, the controllers aren't loaded when you click on the links, and an error message is shown in the console.

3 Answers 3

1

I personally user ui router with the $ocLazyLoad provider https://github.com/ocombe/ocLazyLoad

Its more simple and works great. Here is a example:

     .state('dashboards.dashboard_2', {
                url: "/dashboard_2",
                templateUrl: "views/dashboard_2.html",
                data: { pageTitle: 'Dashboard 2' },
                resolve: {
                    loadPlugin: function ($ocLazyLoad) {
                        return $ocLazyLoad.load([
                            {
                                serie: true,
                                name: 'angular-flot',
                                files: [ 'js/plugins/flot/jquery.flot.js', 'js/plugins/flot/jquery.flot.time.js', 'js/plugins/flot/jquery.flot.tooltip.min.js', 'js/plugins/flot/jquery.flot.spline.js', 'js/plugins/flot/jquery.flot.resize.js', 'js/plugins/flot/jquery.flot.pie.js', 'js/plugins/flot/curvedLines.js', 'js/plugins/flot/angular-flot.js', ]
                            },
                            {
                                files: ['js/plugins/jvectormap/jquery-jvectormap-2.0.2.min.js', 'js/plugins/jvectormap/jquery-jvectormap-2.0.2.css']
                            },
                            {
                                files: ['js/plugins/jvectormap/jquery-jvectormap-world-mill-en.js']
                            },
                            {
                                name: 'ui.checkbox',
                                files: ['js/bootstrap/angular-bootstrap-checkbox.js']
                            }
                        ]);
                    }
                }
            })
Sign up to request clarification or add additional context in comments.

3 Comments

I found that after I posted my answer, it looks pretty useful. I'll check it out, thanks :)
After having investigated ocLazyLoad, it seems like it doesn't handle dependencies, so I have to go back to specifying all of the file names manually. Is that true?
How so? Because in that example, all that scripts are depencencies for the module to work.
0

Try this:

resolve: {
      require: function ($q) {
        //tell ui-router to wait
        var deferred = $q.defer(); 
          console.log('security/register.controller loading')

          require(['security/register.controller'], function () {
            console.log('security/register.controller loaded')
            deferred.resolve()
          });
         return deferred.promise; 
      }

3 Comments

I tried that and got the same result. The interesting thing is that if I add the require statement earlier in my code it also fails to load, so I think it's something to do with how I'm organising and loading my modules.
what does your controller looks like? do you have require as one of inject params
I've tried it both with the inject param and without. It's calling it in the correct order even without the param, but still not loading properly.
0

It turns out the problem was with my flawed assumption that you could add a controller to angular after bootstrap, which apparently you can, just not the same way as you do pre-bootstrap. If you're adding them after bootstrap you need to cache a copy of the controller provider, and then register the controller with that provider. I added the following code:

var app = angular.module('app', ['ui.router'])

var cachedProviders = {}
  app.config(['$controllerProvider',
    function(controllerProvider) {
      cachedProviders.$controllerProvider = controllerProvider;
    }
  ]);
  $(function (){
    app.controller = function (name, controller) {
      console.log('Loading (using post-boostrap loader):', name)
      cachedProviders.$controllerProvider.register.apply(this, arguments)
    }
  })

To my app module file and it started working. I'm not quite sure if this will have negative side effects yet, but for now it does what I want.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.