gulp-angular-templatecache Module is not available - javascript

I am using gulp-angular-templacache.
I have that task that should create a module named templates and I added it as a dependency to my app module:
Configurations:
templateCache: {
file: 'tempaltes.js',
options: {
module: 'templates',
standalone: true,
root: 'app/'
}
}
App module:
var App = angular.module('app', [
'templates']);
Gulp task:
gulp.task('templatecache', ['clean-code'], function() {
log('Creating AngularJS $templateCache');
return gulp
.src(config.htmltemplates)
.pipe($.minifyHtml({empty: true}))
.pipe($.angularTemplatecache(
config.templateCache.file,
config.templateCache.options
))
.pipe(gulp.dest(config.temp));
});
But, when I try to run this I am always getting that error message:
Uncaught Error: [$injector:nomod] Module 'templates' 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.
I tried to make the templatescache also not standalone and removing the dependency but without success...
What should I do ??

Seems you are loading template.js, after the module app definition. You can load the file before your angular app file
OR, Don't define a standalone module.
Configuration
templateCache: {
file: 'tempaltes.js',
options: {
module: 'templates',
standalone: false,
root: 'app/'
}
}
Angualr
//Define the module
angular.module('templates', []);
var App = angular.module('app', ['templates']);

Related

Unit testing AngularJS application with karma-browserify

I'm trying to unit test an AngularJS/Browserify application via karma-browserify. Ultimately, when I run my gulp karma task, I get the error Error: [$injector:nomod] Module 'myApp' is not available! You either misspelled the module name or forgot to load it...
My gulpfile.js has the task
gulp.task('test', function(done) {
new karma.Server({
configFile: __dirname + '/karma.conf.js'
}, done).start();
});
My karma.conf.js includes
{
// ...
frameworks: ['browserify', 'jasmine'],
files: [
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'spec/**/*.js'
],
preprocessors: {
'spec/**/*.js': [ 'browserify' ]
},
browserify: {
debug: true
}
// ...
}
I define my module in a main.js that includes
require('angular').module('myApp', [
//...lots of `require`s for each dependency...
]);
I define my controller in a MainCtrl.js that looks like
function MainCtrl(/*...deps...*/) {
var ctrl = this;
ctrl.foo = 'bar';
}
module.exports = MainCtrl;
then register the controller elsewhere like
var app = require('angular').module('myApp');
app.controller('MainCtrl', [/*...deps...*/, require('./MainCtrl')]);
Finally my test looks like
(function() {
"use strict";
describe('MainCtrl', function() {
var ctrl;
beforeEach( angular.mock.module('myApp') );
beforeEach( inject( function($controller) {
ctrl = $controller('MainCtrl');
}));
it('should be defined', function() {
expect(ctrl).toBeDefined();
});
});
}());
Workaround
The workaround I have is to add my main.js file to karma.conf.js
files: [
'js/main.js', // ADDED: Defines the app and `require`s angular
'node_modules/angular-mocks/angular-mocks.js',
'spec/**/*.js'
],
preprocessors: {
'js/main.js': ['browserify'], // ADDED
'spec/**/*.js': ['browserify']
}
and everything works. But I thought I wasn't supposed to add my source files to karma (at least not with karma-browserify). Is this the right way to set up my project?
Yes, the 'workaround' is the desired way to use karma-browserify.
preprocessors definition specifies which of the included files should be processed by which preprocessor but does not include them:
The keys of the preprocessors config object are used to filter the
files specified in the files configuration.
it is files definition that actually includes the files:
The files array determines which files are included in the browser and
which files are watched and served by Karma.
Files tells Karma which files it should load relative to the base path. These are:
All test related libraries
Our source code to test
The tests themselves

Why my AngularJS + RequireJS application is not building via grunt-contrib-requirejs?

I have src of my application. I use AngularJS. I use RequireJS as module loader. I use Grunt as task runner. When I run application using src: everything is good. When I build application with Grunt, application is not working. I got no errors in console.
Main thing I noticed: my code (code of my application: app.js and files under js/) does not appear in output file which is set in grunt task settings. Also, I don't think there is something about AngularJS.
Main config file:
require.config({
paths: {
'angular' : '../components/angular/angular',
/* etc..... */
'jquery': '../components/jquery/dist/jquery',
'application': './app'
},
shim: {
/* etc */
application: {
deps: ['angular']
},
angular: {
exports : 'angular'
}
},
baseUrl: '/js'
});
require(['application', 'angular', 'ngRoute', 'bootstrap' /* ngRoute and bootstrap from etc :) */], function (app) {
app.init();
});
My app in app.js is:
define([
'require', 'angular', 'main/main', 'common/common'
], function (require) {
'use strict';
var angular = require('angular');
var app = angular.module('myApp', ['ngRoute', 'main', 'common']);
app.init = function () {
angular.bootstrap(document, ['myApp']);
};
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider
./* ... some code */
}
]);
return app;
});
I add main RequireJS config file at the end of body tag:
<script type="text/javascript" src="components/requirejs/require.js" data-main="js/bootstrap.js"></script>
Now I have problem. I have Grunt as build system. I have this task:
grunt.initConfig({
requirejs: {
compile: {
options: {
baseUrl: "public/js",
mainConfigFile: "public/js/bootstrap.js",
name: 'bootstrap',
out: "build/js/bootstrap.js",
optimize: 'none'
}
}
},
// etc
I have no optimisation, so I get ~11k lines of code in output file.
As I said. Main problem is: no AngularJS code and no application code in output file.
Why? I set up mainConfigFile correctly. Problem is in RequireJS config file? But everything is okay, when I am running my app on src.
It would be better if you can provide the exactly error output you get. And where you got it (from browser's console or from terminal during build process)
For now I will suggest some adjustments what could possibly help with your case.
angular: {
exports : 'angular'
}
Here you have already export angular.js into global local variable (inside every require and define block).
And by doing var angular = require('angular'); you are possibly asynchronously override angular variable inside your app.js module.
For 'require' being added into define block, as r.js always reading what module got to be loaded in very first step, and then merged into single file. And this may confuse r.js to merging requireJS into itself.
Suggest this adjustment for your app.js:
define([ // Removed 'require' because no needed , it is already global and usable anywhere
'angular', 'main/main', 'common/common'
], function () {
'use strict';
// var angular = require('angular'); // This is a very common mistake. You are not going to call angular this way, requireJS difference with commonJS.
var app = angular.module('myApp', ['ngRoute', 'main', 'common']);
app.init = function () {
angular.bootstrap(document, ['myApp']);
};
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider
./* ... some code */
}
]);
return app;
});
And last but not least data-main="js/bootstrap.js" I think it should be js/main.js or a typo.
EDIT added explanations for 'require' in define block, and angular local variable.

Setting up Jasmine/karma for angular

I am lightly following this guide - http://paislee.io/testing-angularjs-with-grunt-karma-and-jasmine/ - and having a few issues as follows:
Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:modulerr] Failed to instantiate module ngRoute due to:
Error: [$injector:nomod] Module 'ngRoute' 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.
I installed everything as it told me to and found another pretty basic example of setting up a test(this is my first time implementing so I'm starting small), the test looks like so
describe('Unit: MainCtrl', function() {
// Load the module with MainCtrl
beforeEach(module('myApp'));
var ctrl, scope;
// inject the $controller and $rootScope services
// in the beforeEach block
beforeEach(inject(function($controller, $rootScope) {
// Create a new scope that's a child of the $rootScope
scope = $rootScope.$new();
// Create the controller
ctrl = $controller('MainCtrl', {
$scope: scope
});
}));
it('should create $scope.greeting when calling sayHello',
function() {
expect(scope.greeting).toBeUndefined();
scope.sayHello();
expect(scope.greeting).toEqual("Hello Ari");
});
})
And in the controller it's just
$scope.name = "Ari";
$scope.sayHello = function() {
$scope.greeting = "Hello " + $scope.name;
}
(this is from http://www.ng-newsletter.com/advent2013/#!/day/19 )
I have my app set up and controllers in separate folders, using a regular ng-route structure, I'm thinking this maybe is the issue? I'm using grunt karma for this - here is the task just incase it's helpful.
karma: {
unit: {
options: {
frameworks: ['jasmine'],
singleRun: true,
browsers: ['PhantomJS'],
files: [
'app/bower_components/angular/angular.js',
'app/bower_components/angular-mocks/angular-mocks.js',
'app/scripts/**/*.js'
]
}
}
}
I could use some help, this is my first time attempting this, I would LOVE to get some automated testing in place. Thanks for reading!!
You need to include ngRoute in your files list in the karma conf. The error message says as much.
karma: {
unit: {
options: {
frameworks: ['jasmine'],
singleRun: true,
browsers: ['PhantomJS'],
files: [
'app/bower_components/angular/angular.js',
'app/bower_components/angular-mocks/angular-mocks.js',
'app/bower_components/angular-mocks/angular-route.js',
'app/scripts/**/*.js'
]
}
}
}
You have not included ngroute module, as there is some dependency on this module.
There should be a bower component
'app/bower_components/angular-route/angular-route.js',
Install this bower component and add this line to karma config.
Check for other module too.

Built RequireJS app won't load

So, I built my RequireJS app using grunt-require, which I believe uses r.js behind the scenes. However, upon running the app, I get this every time:
Uncaught Error: Module name "underscore" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded require-2.1.9.min.js:8
GET http://localhost:8080/resources/js/app/App.js 404 (Not Found) require-2.1.9.min.js:34
Uncaught Error: Script error for: app/App
http://requirejs.org/docs/errors.html#scripterror
My "main" script is in app/Main.js and looks like this:
require(['common'], function() {
'use strict';
require(['app/App'], function(app) {
app.start();
});
});
And then the build options for grunt-require:
requirejs: {
options: {
baseUrl: 'resources/js',
dir: 'resources/js/build',
main: 'app/Main',
out: null,
optimize: 'uglify2',
skipDirOptimize: true,
priority: ['common'],
preserveLicenseComments: false,
modules: [
{
name: 'common'
},{
name: 'app/Main',
exclude: ['common'],
include: ['app/App']
}
],
paths: { ... },
shim: { ... }
}
}
As you can see, I've included app/App in the build of app/Main.js.
It loads Main.js and common.js separately, as expected, but then it tries to load app/App.js separately. When I look in the built version of Main.js, I see that app/App.js has in fact been built in.
Any ideas why it's trying to load app/App.js separately?
It seems, you forgot findNestedDependencies : true option in your build config and your nested require did not load. See its description.

RequireJS Setting Path to the Parent Level

In order to direct my models, collections, etc. from my mobile app to my web app, I need to configure my RequireJS.
I have the following file structure:
/
/js
/models
/mobile
/js
/templates
I want my mobile app to use my main app's models, so I set the following:
require.config( {
paths : {
models : '/js/models',
templates : 'mobile/templates'
}
});
And I get these errors in Chrome:
Uncaught SyntaxError: Unexpected token < /mobile/js/models/User.js?bust=0.1.0:1
Uncaught SyntaxError: Unexpected token < /mobile/js/models/InviteRequest.js?bust=0.1.0:1
Uncaught SyntaxError: Unexpected token < /mobile/js/models/Log.js?bust=0.1.0:1
Meaning that it's still looking in /mobile instead of /.
This path config works for my templates folder, but not my models folder. How can I point all require dependencies that start with models/ to my main models folder?
Thanks!
ATTEMPT 2
I tried setting the baseUrl instead:
require.config( {
baseUrl : '/',
paths : {
views : 'mobile/views',
templates : 'mobile/templates'
}
});
require( [
'app'
],
function(App) {
App.initialize();
});
I get the error:
GET http://local.m.mysite.co/app.js 404 (Not Found) require.js:2
In your second attempt, you basically tell Require JS to load 'app' module and since you set the base url to '/', Require JS will look 'app' module in your root path.
So what you need to do is to tell Require JS where to look for your 'app' module. Say your 'app' module is in /js/module:
/
/js
/models
/module
/app.js
/mobile
/js
/templates
Then your code to load 'app' module is:
require.config( {
baseUrl : '/',
paths : {
views : 'mobile/views',
templates : 'mobile/templates'
}
});
require( [
'js/module/app'
],
function(app) {
app.initialize();
});
Alternatively, you can set 'module' path in your config. Then refer to this path in your dependency loading:
require.config( {
baseUrl : '/',
paths : {
views : 'mobile/views',
templates : 'mobile/templates',
module: 'js/module'
}
});
require( [
'module/app'
],
function(app) {
app.initialize();
});
As for the error you get in Chrome before your ATTEMPT 2, you will need to look at how you refer to your module in module loading.

Categories

Resources