Error: $injector:modulerr Module Error on running the application? - javascript

I am getting an angular module error whenever I am trying to inject dependencies using require.js
My bower.json file :
{
"name": "asa",
"version": "1.0",
"authors": [
"asda"
],
"description": "aaaa",
"dependencies": {
"angular": "1.3.8",
"angular-route": "1.3.8",
"requirejs": "2.1.15",
},
"license": "sss",
"homepage": "index.html",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"src/main/webapp/resources/bower_components",
"test",
"tests"
]
}
Main.js
var app = angular.module('myApp', ['route']);
app.service('abc', function () {
//some content
});
app.service('def', function( $http, $q ) {
//some content
});
var zzz = app.controller('zzz', function ($scope, $http, $filter, abc, def) {
//controller content
});
zzz.$inject = ['$scope', '$filter','abc','def'];
my data-main file containing the dependencies : main-di.js
require.config({
paths: {
angular: '../lib/dependencies/bower_components/angular/angular',
route: '../lib/dependencies/bower_components/angular-route/angular-route',
myApp: "person"
},
shim: {
angular: {
exports: "angular"
},
route: {
deps: ['angular']
},
myApp: {
deps: [ 'angular', 'route']
}
}
});
require(['myApp'], function () {
angular.bootstrap(document.getElementById('myApp'), ['myApp']);
});
On running the application i get the following error-
Error :
TypeError: e is undefined
...a("$ngControllerController",f));w(a)}}}n=e.module("ngRoute", ["ng"]).provider("$r...
Error: [$injector:modulerr] Failed to instantiate module myApp due to:
[$injector:nomod] Module 'myApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
http://errors.angularjs.org/1.3.8/$injector/nomod?p0=myApp minErr/<#http://localhost:8080/AngularJsInJava/lib/dependencies/bower_components/angular/angular.js:63:12
Can anybody please help me as to why I am getting this error??

This is not correct way to define controller.
var zzz = app.controller('zzz', function ($scope, $http, $filter, abc, def) {
//controller content
});
Create controller this way..
app.controller('zzz', ZzzCtrl);
ZzzCtrl.$inject = ['$scope', '$filter','abc','def'];
function ZzzCtrl ($scope, $filter, abc, def) {
// controller code here
}
Also if you use minification for your angular Code, you should always use annotations or "$inject"s . Not with controllers only.
eg.
angular.module('someModule').service('someService',['$someInjection', function($someInjection){}])

Related

Use Jasmine to test a service with uibModal and lodash as dependencies

This is my first time using Jasmine, and I have tested my first Factory without problems.
But now, I want to test this Service:
angular.module('Questions', [])
.service('QuestionsService', function($uibModal, $log, _) {
...
}
$uibModal is from UI Bootstrap (see here) and _ is Lodash.
My Jasmine test so far is:
describe('Service: QuestionsService', function() {
var QuestionsService;
beforeEach(inject(function(_QuestionsService_) {
QuestionsService = _QuestionsService_;
}));
...
}
And when I try it (grunt test), I get the following error:
Error: [$injector:unpr] Unknown provider: $uibModalProvider <- $uibModal <- QuestionsService
And at some point I also had:
Error: [$injector:unpr] Unknown provider: _Provider <- _ <- QuestionsService
If it can help, my Karma conf is:
module.exports = function(config) {
'use strict';
config.set({
autoWatch: true,
basePath: '../',
frameworks: [
"jasmine"
],
// list of files / patterns to load in the browser
files: [
// bower:js
'bower_components/jquery/dist/jquery.js',
'bower_components/lodash/lodash.js',
'bower_components/angular/angular.js',
'bower_components/bootstrap-sass-official/assets/javascripts/bootstrap.js',
'bower_components/angular-animate/angular-animate.js',
'bower_components/angular-cookies/angular-cookies.js',
'bower_components/angular-resource/angular-resource.js',
'bower_components/angular-route/angular-route.js',
'bower_components/angular-sanitize/angular-sanitize.js',
'bower_components/angular-touch/angular-touch.js',
'bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
'bower_components/angular-mocks/angular-mocks.js',
// endbower
"app/scripts/**/*.js",
"test/mock/**/*.js",
"test/spec/**/*.js",
],
exclude: [
],
port: 8080,
browsers: [
"PhantomJS"
],
plugins: [
"karma-phantomjs-launcher",
"karma-jasmine"
],
singleRun: false,
colors: true,
logLevel: config.LOG_INFO,
});
};
Just in case others find this. To solve the error when testing a directive's controller, I mocked the $uibModal service, conceptually like this:
describe('Service: QuestionsService', function() {
var controller;
beforeEach(inject(function($controller) {
controller = $controller('controllerName', {
$uibModal : {}
});
}));
...
}
$uibModal may need to be more than just an empty object if you are writing tests against controller functions that interact with it.
The app's module was not included in the test. The refactored test for the QuestionService would be:
describe('Service: QuestionsService', function() {
var QuestionsService;
// The module needs to be included in the test.
beforeEach(module('boardgameApp'));
beforeEach(inject(function(_QuestionsService_) {
QuestionsService = _QuestionsService_;
}));
...
}

Requirejs optimizer with angularjs

I am trying to make a sample application using angularjs, ui-router and requirejs to lazyload my controllers. It works good locally but I want to write requirejs optimizer for production environment, Tried using grunt:requirejs tool for this but it didnt work for me. It doesnt even give any script loading error or something..
<--index.html--!>
<!DOCTYPE html>
<html style="overflow-x:hidden">
<head>
</head>
<body class="no-padding">
<div data-ui-view="header"></div>
<div data-ui-view="module"></div>
<script data-main="app/main" src="bower_components/requirejs/require.js"></script>
</body>
</html>
//main.js
require.config({
baseUrl: "",
// Paths for just the core application and its controllers/factories/services
paths: {
"jquery": "bower_components/jquery/dist/jquery",
"angular": "bower_components/angular/angular.min",
"angular-ui-router": "bower_components/angular-ui-router/release/angular-ui-router.min",
"app": "app/app",
"underscore": "node_modules/underscore/underscore-min",
},
shim: {
//Tell requirejs to pipe in angular"s return variable as "angular"
"angular": {
exports: "angular"
},
},
// Say we have a dep on App, so it gets loaded
deps: ["app", 'lib']
});
//lib.js
define([
'jquery',
'underscore',
], function($){
});
//app.js
define([
'angular',
'angular-ui-router'
], function(){
var app = angular.module('app', ['ui.router']);
//lazy loading
var loadController = function(path){
return ['$q', function($q){
var defered = $q.defer();
require([path], function(){
defered.resolve();
});
return defered.promise;
}]
};
app.config(['$controllerProvider', function($controllerProvider){
app.registerController = $controllerProvider.register;
}]);
app.config(['$stateProvider', function($stateProvider){
//registering controller
// defining states
$stateProvider.state('app', {
url: '/',
views: {
'header':{
templateUrl:"<div>{{title}}</div>",
controller:"appCtrl"
},
'module':{
template:"<div>{{title}}</div>",
controller:"homeCtrl"
}
},
resolve: {
loadApp: loadController('../app/controllers/header'),
loadHome: loadController('../app/controllers/home')
}
});
}]);
angular.bootstrap(document, ['app']);
return app;
});
//home.js
define(function(){
angular.module('app').registerController('homeCtrl', ['$scope', '$state', function($scope,$state){
$scope.title = 'CONTENT';
}]);
});
//header.js
define(function(){
angular.module('app').registerController('appCtrl', ['$scope', '$state', function($scope,$state){
$scope.title = 'HEADER';
}]);
});
I was using grunt:requirejs task to compile an optimized dist file "main.js" and grunt copy for modified index.html inside dist directory:
grunt:requirejs and modified index.html -->
grunt.initConfig({
//...
requirejs: {
compile: {
options: {
name: 'node_modules/almond/almond',
mainConfigFile: 'app/main.js',
out: 'dist/main_opt.js',
baseUrl: './'
}
}
},
//...
})
<--dist/index.html--!>
<!DOCTYPE html>
<html style="overflow-x:hidden">
<head>
</head>
<body class="no-padding">
<div data-ui-view="header"></div>
<div data-ui-view="module"></div>
<script src='bower_components/requirejs/require.js'></script>
<script>
require.config({
paths: {
//Comment out this line to go back to loading
//the non-optimized main.js source file.
"main_opt": "dist/main_opt"
}
});
require(["main_opt"]);
</script>
</body>
</html>
When loading dist/index.html it gives me nothing, no error in browser, just doesnt work, if it was giving me script loading error for controllers it might have made any sense but its not. Completely clueless here..
There is nothing required in main.js file. You must require at least one of files declared in paths. Do it as follow:
require(['app'], function () {
console.log('app required successfully');
});
Put this lines of code in your main.js file. I hope it may help to find errors:
requirejs.onError = function (err) {
console.error('[require error] type: ', err.requireType, ' ,modules: ' + err.requireModules);
throw err;
};

ReferenceError: Can't find variable: module in angular testing

I'm trying to write a test for my Angular controller, I'm using jasmine karma and angular-mocks, but keeps on getting the error ReferenceError: Can't find variable: module.
I had a bit of a search, but I already have the angular-mocks in my bower.
What could I be missing here?
The following is my code:
#controller
angular.module('cook_book_ctrl', [])
.controller('cookBookCtrl', function($scope, CookBook, CookBookRecipesService){
$scope.cookbookoptions = true;
CookBook.list()
.success(function(data){
$scope.recipeList = data;
CookBookRecipesService.loadCookBookRecipes($scope.recipeList);
})
.error(function(error){
})
});
#controller test
describe('CookBook controller spec', function(){
var $httpBackend, $rootScope, createController, authRequestHandler
beforeEach(module('cook_book_ctrl'));
})
#bower.json
{
"name": "HelloIonic",
"private": "true",
"devDependencies": {
"ionic": "driftyco/ionic-bower#1.0.0",
"ionic-service-analytics": "master",
"ionic-service-core": "~0.1.4",
"angular-mocks": "1.3.13"
},
"dependencies": {
"ng-cordova-oauth": "~0.1.2",
"ng-tags-input": "~2.3.0",
"angular": "~1.4.0",
"underscore": "~1.8.3",
"materialize": "~0.97.0"
},
"resolutions": {
"angular": "~1.4.0"
}
}
beforeEach(module('cook_book_ctrl'));
})
UPDATE: Screenshot added for clarity
Besides installing angular-mocks through bower, remember to add reference to angular-mocks.js in your karma config file, like below
config.set({
basePath: '../',
port: '8000',
files: [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
...
]
In my case it was also about wrong order of files path in karma.conf.js.
Was:
// list of files / patterns to load in the browser
files: [
'tests/*.test.js', // this should not be as first!
'bower_components/angular/angular.min.js',
'bower_components/angular-mocks/angular-mocks.js',
'app/*.js',
],
Should be:
// list of files / patterns to load in the browser
files: [
'bower_components/angular/angular.min.js',
'bower_components/angular-mocks/angular-mocks.js',
'app/*.js',
'tests/*.test.js' // now it's cool
],
Maybe obvious thing or maybe not? ;-)

Obfuscating js files with grunt-obfuscator: Uncaught ReferenceError: require is not defined

I was searching over the internet about how to obfuscate my JavaScript code and after use uglify that convert all my files minified but not obfuscated I decided to use grunt-obfuscator
After make this configuration on my simple project:
Gruntfile.js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-obfuscator');
grunt.initConfig({
connect: {
server: {
options: {
port: 9000,
base: 'app/'
}
}
},
watch: {
project: {
files: ['app/**/*.js', 'app/**/*.html', 'app/**/*.json', 'app/**/*.css'],
options: {
livereload: true
}
}
},
obfuscator: {
files: [
'app/js/app.js',
'app/js/controllers.js'
],
entry: 'app/js/app.js',
out: 'app/js/obfuscated.js',
strings: true,
root: __dirname
}
});
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['obfuscator', 'connect', 'watch']);
};
My app.js
(function () {
var app = angular.module('myapp', [
'ngRoute',
'myapp.controllers'
]);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/home.html'
})
.otherwise({
redirectTo: '/'
});
}]);
})();
My controller.js
(function() {
angular.module('myapp.controllers', [])
.controller('AppController', ['$scope',
function ($scope) {
$scope.name = "Test123";
}]);
})();
After execute grunt my obfuscated.js is really hard to read, which is really great. So I'm enter to my localhost which is loading now the obfuscated.js file but I'm getting this error:
Uncaught ReferenceError: require is not defined
What am I missing?
My obfuscated.js
!function(a,b){function c(b,d){var e,f;if("\x2e"!=b[0]&&"\x2f"!=b[0])return a(b);if(d=d||"\x72\x6f\x6f\x74",e=c.resolve(b),!e&&/\.json$/i.test(b))return a("\x2e\x2f"+c.basename(b));if(f=c.cache[e],!f)try{return a(b)}catch(g){throw Error("\x66\x61\x69\x6c\x65\x64\x20\x74\x6f\x20\x72\x65\x71\x75\x69\x72\x65\x20\x22"+b+"\x22\x20\x66\x72\x6f\x6d\x20"+d+"\n"+g.message+"\n"+g.stack)}return f.exports||(f.exports={},f.call(f.exports,f,f.exports,c.relative(e))),f.exports}c.cache={},c.basename=a("\x70\x61\x74\x68").basename,c.resolve=function(b){var d,e,f;if("\x2e"!=b[0])return a.resolve(b);for(d=[b,b+"\x2e\x6a\x73",b+"\x2f\x69\x6e\x64\x65\x78\x2e\x6a\x73",b+"\x2e\x6a\x73\x6f\x6e",b+"\x2f\x69\x6e\x64\x65\x78\x2e\x6a\x73\x6f\x6e"],e=0;f=d[e];e++)if(c.cache[f])return f},c.register=function(a,b){c.cache[a]=b},c.relative=function(a){function b(b){var d,e,f,g,h;if("\x2e"!=b[0])return c(b);for(d=a.split("\x2f"),e=b.split("\x2f"),d.pop(),f=0,g=e.length;g>f;f+=1)h=e[f],"\x2e\x2e"==h?d.pop():"\x2e"!=h&&d.push(h);return c(d.join("\x2f"),a)}return b.resolve=c.resolve,b.cache=c.cache,b},c.register("\x2e\x2f\x61\x70\x70\x2f\x6a\x73\x2f\x61\x70\x70\x2e\x6a\x73",function(a,b,c){!function(){var a=angular.module("\x6d\x79\x61\x70\x70",["\x6e\x67\x52\x6f\x75\x74\x65","\x6d\x79\x61\x70\x70\x2e\x63\x6f\x6e\x74\x72\x6f\x6c\x6c\x65\x72\x73"]);a.config(["\x24\x72\x6f\x75\x74\x65\x50\x72\x6f\x76\x69\x64\x65\x72",function(a){a.when("\x2f",{templateUrl:"\x76\x69\x65\x77\x73\x2f\x68\x6f\x6d\x65\x2e\x68\x74\x6d\x6c"}).otherwise({redirectTo:"\x2f"})}]),c.extensions["\x2e\x73\x65\x72\x76\x65\x72\x2e\x63\x6f\x6e\x74\x72\x6f\x6c\x6c\x65\x72\x2e\x6a\x73"]=c.extensions["\x2e\x6a\x73"],c.extensions["\x2e\x73\x65\x72\x76\x65\x72\x2e\x6d\x6f\x64\x65\x6c\x2e\x6a\x73"]=c.extensions["\x2e\x6a\x73"],c.extensions["\x2e\x73\x65\x72\x76\x65\x72\x2e\x72\x6f\x75\x74\x65\x73\x2e\x6a\x73"]=c.extensions["\x2e\x6a\x73"]}()}),c.register("\x2e\x2f\x61\x70\x70\x2f\x6a\x73\x2f\x63\x6f\x6e\x74\x72\x6f\x6c\x6c\x65\x72\x73\x2e\x6a\x73",function(){!function(){angular.module("\x6d\x79\x61\x70\x70\x2e\x63\x6f\x6e\x74\x72\x6f\x6c\x6c\x65\x72\x73",[]).controller("\x41\x70\x70\x43\x6f\x6e\x74\x72\x6f\x6c\x6c\x65\x72",["\x24\x73\x63\x6f\x70\x65",function(a){a.name="\x54\x65\x73\x74\x31\x32\x33"}])}()}),b.exports=c("\x2e\x2f\x61\x70\x70\x2f\x6a\x73\x2f\x61\x70\x70\x2e\x6a\x73")}(require,module);
UPDATE
There is no answer for this question since this plugin is not created for angularjs, only for Node.js. And the creator has not the minimal intention to make it for angular js. However it is a cool tool
there are several questions here.
Do I need to obfuscate all my js files in order to get this run?
no
An obfuscate file can work perfect with all your dependencies NON-obfuscated? yes
What am I missing?
Hard to tell, uglification can be very tricky.
First I'll verify if dependencies injections are well done or you can use ngAnnotate to do that for you
dependency shall be defined as example bellow:
.service('myService',['$rootScope',function($rootScope){ ... }]);
If that does not solve your issue, you have to dig on requireJS that seems to send an issue
Edit your code and paste your main.js for us see what you are trying to uglify

Requirejs dependency not working

I am trying to use angular-ladda directive in my app. Here is my main.js which is the requirejs manifesto file:
requirejs.config({
paths: {
underscore: 'lib/underscore/underscore',
angular: 'lib/angular/angular',
jquery: 'lib/jquery/dist/jquery.min',
'angular-route': 'lib/angular-route/angular-route',
'controllers': 'js/controllers',
'services': 'js/services',
'providers': 'js/providers',
'filters': 'js/filters',
'directives': 'js/directives',
'app': 'js/app',
'spin': 'lib/ladda/dist/spin.min',
'ladda': 'lib/ladda/js/ladda',
'ngLadda': 'lib/angular-ladda/src/angular-ladda'
},
shim: {
underscore: {
exports: '_'
},
'angular': {
exports: 'angular'
},
'states': {
deps: ['angular'],
exports: 'states'
},
'angular-route': {
deps: ['angular']
},
'ladda': {
deps: ['spin'],
exports: 'Ladda'
},
'ngLadda': {
deps: ['ladda']
}
},
priority: [
'angular'
]
});
requirejs(['angular',
'app',
'underscore',
'js/routes',
'jquery',
'services/services',
'providers/providers',
'directives/directives',
'filters/filters',
'controllers/controllers',
'ngLadda'
], function (angular, app, _) {
angular.element(document).ready(function () {
angular.bootstrap(document, ['App']);
document.getElementsByTagName('html')[0].dataset.ngApp = 'App';
});
});
Here is the ladda directive:
/**!
* AngularJS Ladda directive
* #author Chungsub Kim <subicura#subicura.com>
*/
/* global Ladda */
(function () {
'use strict';
angular.module('angular-ladda', []).directive(
'ladda',
[
'$compile',
function ($compile) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.addClass('ladda-button');
if(angular.isUndefined(element.attr('data-style'))) {
element.attr('data-style', 'zoom-in');
}
var ladda = Ladda.create( element[0] ); //here is were Ladda is not defined
$compile(angular.element(element.children()[0]).contents())(scope);
scope.$watch(attrs.ladda, function(loading) {
if(loading || angular.isNumber(loading)) {
if(!ladda.isLoading()) {
ladda.start();
}
if(angular.isNumber(loading)) {
ladda.setProgress(loading);
}
} else {
ladda.stop();
}
});
}
};
}
]
);
})();
In the directive code (line 22, where commented) there is an erroe "Ladda is not defined".
If I will add the following line:
var Ladda = require('ladda');
It all will work, so why the dependency in the main.js not doing this already?
Can you please help me with this one?
I think for the dependency to work, you'd have to define ngLadda declaration as a module
define(function (require) {
// your ngLadda declaration here
}
Edit: there is another possibility
When you look at code of Ladda:
https://github.com/hakimel/Ladda/blob/master/js/ladda.js
You see that Ladda is being wrapped in define(){}
// AMD module
else if( typeof define === 'function' && define.amd ) {
define( [ 'spin' ], factory );
}
In requireJS docs it's stated that:
Only use other "shim" modules as dependencies for shimmed scripts, or AMD libraries that have no dependencies and call define() after they also create a global (like jQuery or lodash). Otherwise, if you use an AMD module as a dependency for a shim config module, after a build, that AMD module may not be evaluated until after the shimmed code in the build executes, and an error will occur. The ultimate fix is to upgrade all the shimmed code to have optional AMD define() calls.
http://requirejs.org/docs/api.html#config-shim
So, Ladda is an AMD module with deps already defined. In your main.js put it outside of shim:
'ladda': {
exports: 'Ladda'
},
'ngLadda': {
deps: ['ladda']
}
shim: {
//your other shimmed modules
}
Put your ngLadda in define(function(require){}) like it's said in original answer, but don't put any dependencies inside.

Categories