javascriptangularjs

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);
    
})();

Solution

  • 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.