0

I want 'MyController2' to inherit 'MyController1', however, both controllers are lazyloaded using ocLazyLoad. According to Jussi Kosunen's answer to this question (https://stackoverflow.com/a/15292441/2197555), I have made a function registerDynamic() to register the controllers, but it still reports the following error at the line with '$controller' in controller1.js:

Error: [$injector:unpr] Unknown provider: $elementProvider <- $element <- DataTableController

My codes are like this.

First file controller1.js:

angular.module( 'myApp',[])
    .controller( 'MyController1', [ function($scope){
        // ...
    }]);

Second file controller2.js:

angular.module( 'myApp')
    .controller( 'MyController2', [ '$controller', '$scope',function($controller, $scope){
         $controller('MyController1', {$scope: $scope }); // here triggers error '[$injector:unpr] Unknown provider'
         // ...
    }]);

In the third File lazy-load.js, I lazyload the above two .js files:

var app = angular.module('myApp'),
queueLen = app._invokeQueue.length;
app.directive( 'LazyLoad', [ function( ){
    return {
        restrict: 'EA',
        scope: {
           src: '@',
        },
        link: function( scope, element, attr ){
            var registerDynamic = function() {
                // Register the controls/directives/services we just loaded
                var queue = syncreonApp._invokeQueue;
                for(var i=queueLen;i<queue.length;i++) {
                    var call = queue[i];
                    // call is in the form [providerName, providerFunc, providerArguments]
                    var provider = syncreonApp.providers[call[0]];
                    if(provider) {
                        // e.g. $controllerProvider.register("Ctrl", function() { ... })
                        $log.debug("Registering " + call[1] + " " + call[2][0] + " ...");
                        provider[call[1]].apply(provider, call[2]);
                    }
                }
                queueLen = i;
            },
            loadMultipleJs = function ( js_files ){
                var deferred = $q.defer();
                var js_file1 = js_files.shift(),
                    js_file2 = js_files.shift();

                 $ocLazyLoad.load( js_file1 )
                    .then ( function(){
                        registerDynamic();
                        $ocLazyLoad.load( js_file2 )
                            .then ( function(){
                                registerDynamic();
                                deferred.resolve();
                            }, function(){
                                deferred.reject();
                            });
                    }, function(){
                        deferred.reject();
                    });
           };
           jsonOfJsFilesToLoad = JSON.parse(scope.src);
           loadMultipleJs(jsonOfJsFilesToLoad );
       }
   };
}]);

UPDATE

The official Angular documentation for 'Unknown Provider' error says:

Attempting to inject one controller into another will also throw an Unknown provider error:

Maybe we just cannot injector controller into anther even using $controller service?

Community
  • 1
  • 1
gm2008
  • 4,245
  • 1
  • 36
  • 38
  • Try to inject $controller service into second controller – csharpfolk Jan 28 '16 at 17:41
  • @csharpfolk Thanks for pointing out that. I forgot it when writing the question. I had it in original code. Question edited. – gm2008 Jan 28 '16 at 18:08
  • You can certainly instanitiate another controller inside a controller, see [use case for $controller service in angularjs](http://stackoverflow.com/a/27868095/5535245). So look elsewhere for your problem. Where are you trying to inject `$element`? `$element` is not a service. It is a **local** supplied by `$compile`. – georgeawg Jan 28 '16 at 18:47
  • @georgeawg I don't think I have injected `$element` anywhere. – gm2008 Jan 29 '16 at 09:31

1 Answers1

1

You are taking the error message out of context.

Attempting to inject one controller into another will also throw an Unknown provider error:

angular.module('myModule', [])
   .controller('MyFirstController', function() { /* ... */ })
   .controller('MySecondController', ['MyFirstController', function(MyFirstController) {
     // This controller throws an unknown provider error because
     // MyFirstController cannot be injected.
   }]);

That is not the way you are instantiating controllers.

It specifically says:

Use the $controller service if you want to instantiate controllers yourself.

Which is the way you are instantiating your controllers.

Look for your problem elsewhere.

Your error message:

Unknown provider: $elementProvider <- $element <- DataTableController

The way I read this is that in your DataTableController, you are trying to inject $element. $element is not a service is a local. To inject $element as a local with the $controller service:

$controller('DataTableController', {$scope: $scope, $element: value });
Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • `$element` as a local in controllers injected by `$compile` is documented in [AngularJS $compile API References -- controllers](https://docs.angularjs.org/api/ng/service/$compile#-controller-). `$element` **not a local** in controllers injected by `ngRoute` is documented in [AngularJS ngRoute $route API Reference -- current](https://docs.angularjs.org/api/ngRoute/service/$route#current). What `DataTableController` is doing with `$element` is something you should investigate. – georgeawg Feb 01 '16 at 14:45
  • You are correct. I did use $element in `DataTableController`. It is my error.Thank you very much for the excellent analytic answer. – gm2008 Feb 01 '16 at 15:45