Augusto Herbel
Augusto Herbel

Reputation: 192

AngularJS Error: [ng:areq] Argument 'directiveFactory' is required

I have a web app in which I like to insert my own custom directives, and in order to do that I have defined a new module where I define those new directives (only 1 for now) so I can reuse in the future. The problem comes when AngularJS try to instantiate the new module, I got the following error

(I put only the first part of the log so it doesn't get too difficult to read):

Uncaught Error: [$injector:modulerr] Failed to instantiate module tangoInfinito due to:
Error: [$injector:modulerr] Failed to instantiate module custom.modal due to:
Error: [ng:areq] Argument 'directiveFactory' is required
http://errors.angularjs.org/1.5.9/ng/areq?p0=directiveFactory&p1=required
    at http://localhost/tangoinfinito.com.ar/js/Dependencies/angular/angular.js:68:12
    at assertArg (http://localhost/tangoinfinito.com.ar/js/Dependencies/angular/angular.js:1937:11)
    at $CompileProvider.registerDirective [as directive] (http://localhost/tangoinfinito.com.ar/js/Dependencies/angular/angular.js:7845:7)
    at runInvokeQueue (http://localhost/tangoinfinito.com.ar/js/Dependencies/angular/angular.js:4654:35)
    at http://localhost/tangoinfinito.com.ar/js/Dependencies/angular/angular.js:4662:11
    at forEach (http://localhost/tangoinfinito.com.ar/js/Dependencies/angular/angular.js:325:20)
    at loadModules (http://localhost/tangoinfinito.com.ar/js/Dependencies/angular/angular.js:4644:5)
    at http://localhost/tangoinfinito.com.ar/js/Dependencies/angular/angular.js:4661:40
    at forEach (http://localhost/tangoinfinito.com.ar/js/Dependencies/angular/angular.js:325:20)
    at loadModules (http://localhost/tangoinfinito.com.ar/js/Dependencies/angular/angular.js:4644:5)

also here is my new module:

(function() {
    
    var app = angular.module("custom.modal", []);
    
    // Esta directiva es para generalizar los Modals de Bootstrap 3. No debe ser usada de manera individual,
    // sino como esqueleto de Modals personalizados en otras directivas.
    var bootstrapModal = function() {
        return {
            restrict: "E",
            template: 
            "<div class='modal fade' tabindex='-1' role='dialog' aria-labelledby='modalTitle'>" +
                "<div class='modal-dialog' role='document'>" +
                    "<div class='modal-content'>" +
                        "{{ htmlModalContent }}" +
                    "</div>" +
                "</div>" +
            "</div>",
            controller: "ModalController"
        }
    };
    
    var ModalController = function($scope) {
        $scope.htmlModalContent = "";
    };

    app
    .controller("ModalController", ModalController)
    .directive("bootstrapModal", bootstrapModal)
    ;
    
})();

I hope you can help me, I searched a lot through the web and I found almost nothing about this error. Thanks in advance.

EDIT: new error after the Phil answer:

Error: [$compile:ctreq] Controller 'bootstrapModal', required by directive 'loginModal', can't be found!

I left you my "loginModal" directive:

    (function() {
        
        var app = angular.module("tangoInfinito");
        
        var loginModal = function() {
            return {
                require: "bootstrapModal",
                link: function(scope, element, attr) {
                scope.htmlModalContent = /* Here comes the template to be inside the modal (the modal body and footer) */
                },
                template: "<bootstrap-modal></bootstrap-modal>"
            }
        };
        
        app.directive("loginModal", loginModal);
    
})();

Upvotes: 3

Views: 4912

Answers (4)

Alexander Taylor
Alexander Taylor

Reputation: 17652

In my case I was deleting a module and deleted its definition but forgot to remove the call to angular.module('',[]).directive():

angular.module('foo.bar.baz', []).directive('someView', someView /* undefined */);

Removing '.directive(...)' fixed the problem.

Upvotes: 0

cmswalker
cmswalker

Reputation: 371

Phil and Faizal have the answers for you above ^^. I have a pre-formatted version below for ease of use. It's worth noting to be very careful when using capitalized directive declartions and all types of definitions for angular API namespaces. It's safe to stick to regular camelCase, it can be one of the tricky gotcha's for those new to angular.

Here are the some of the details

& More naming tips

(function() {

var app = angular.module("custom.modal", []);


app
.controller("modalController", modalController)
.directive("bootstrapModal", bootstrapModal)
;

// Esta directiva es para generalizar los Modals de Bootstrap 3. No debe ser usada de manera individual,
// sino como esqueleto de Modals personalizados en otras directivas.
function bootstrapModal() {
    return {
        restrict: "E",
        template: [
            "<div class='modal fade' tabindex='-1' role='dialog' aria-labelledby='modalTitle'>",
                "<div class='modal-dialog' role='document'>",
                    "<div class='modal-content'>",
                        "{{ htmlModalContent }}",
                    "</div>",
                "</div>",
            "</div>"
        ].join(''),

        controller: "modalController"
    }
};

function modalController($scope) {
    $scope.htmlModalContent = "";
};

})();

Upvotes: 1

Phil
Phil

Reputation: 164913

You are trying to use ModalController and bootstrap_modal before they are defined.

Move their definitions to the top, ie

var bootstrap_modal = function () { ... }
var ModalController = function($scope) { ... }

app
.controller("ModalController", ModalController)
.directive("bootstrap-modal", bootstrap_modal)
;

or define them as functions to take advantage of hoisting, eg

function ModalController($scope) {
  // etc
}

function bootstrap_model() {
  // etc
}

Also, your directive name should be bootstrapModal, ie

app.directive('bootstrapModal', bootstrap_modal)

Update

As for your new error, it seems to relate to $compile. Does your element have both directives, eg <bootstrap-modal login-modal>?

That's what require means but I think you're using it incorrectly.

Upvotes: 3

faizal vasaya
faizal vasaya

Reputation: 492

This a common problem when you use function expression syntax i.e

var ModalController = function($scope) { ... }

As, this prevents you from taking the advantage of JavaScript hoisting. Which can be achieved if you write your function as

function ModalController($scope){....}

Further, you should visit this JavaScript function declaration syntax: var fn = function() {} vs function fn() {} link for detailed difference of the same.

Also, Mozilla docs explains hoisting in detail.

Upvotes: 0

Related Questions