Reputation: 192
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
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
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
(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
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)
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
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