In my AngularJS app, I am trying to create a build using grunt and following plug-ins.
I am able to successfully create the main.js file with all the Javascript code (controllers etc) and also able to append the partials using ngtemplates to main.js.
GruntFile.js
ngtemplates:{
options: {
append: true,
bootstrap: function(module, script) {
return 'require([\'angular\', \'app\'], function(angular, app) { app.run([\'$templateCache\', function($templateCache) {' + script + '}]); });';
}
},
app:{
cwd: 'app',
src: '*/partials/*.html',
dest: 'build/main.js'
}
},
requirejs: {
compile: {
options: {
baseUrl: './app',
mainConfigFile: "./app/main.js",
optimize: 'none',
name: 'main',
out: "./build/<%= pkg.name %>.js",
preserveLicenseComments: false,
paths: {
'domReady': 'empty:',
'angular': 'empty:',
"uiRouter": 'empty:',
"ui-grid": 'empty:',
"ng-dialog": 'empty:',
"jquery": 'empty:',
"ui-bootstrap": 'empty:',
"d3js": 'empty:',
"nvd3": 'empty:',
'angular-nvd3': 'empty:',
'angucomplete-alt': 'empty:',
'spin': 'empty:',
'angular-spinner': 'empty:',
'moment': 'empty:',
'angular-moment': 'empty:',
'angular-sanitize': 'empty:',
'ng-csv': 'empty:',
'ng-cookies': 'empty:'
}
}
}
}
In routes.js I have
define(['app'], function(app) {
'use strict';
return app.config(function($stateProvider) {
var routes = [
{
state: 'home',
url: '/home',
templateUrl: 'app/home/partials/home.html',
controller:'homeController'
}
];
$stateProvider.state(route.state,
{
url: route.url,
// templateUrl: route.templateUrl,
templateProvider: function($templateCache) {
return $templateCache.get(route.templateUrl);
},
controller:route.controller,
params:route.params
}
);
the bootstrap code which was injected by grunt-contrib-requirejs at the end of the build/main.js file.
require(['angular', 'app'], function(angular, app) { app.run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('home/partials/home.html',
"<div class=\"jumbotron text-center\">\r" +
"\n" +
"\t<p>{{message}}</p>\r" +
"\n" +
"</div>"
);
);
}]); });
Now the problem is, the main.js has the bootstrap code at the bottom appended to it. Which puts the templates into $templateCache. But when the application loads, it runs the config code first and then the app.run() is called. Which is obvious. Hence, the $templateCache.get() gets undefined values in routes.js.
How can I tackle this problem?
Thanks for your answers guys. But I found my mistakes. I made a few changes in current implementation and it started working. I am putting it here so it could be helpful to someone like me in future.
I changed my Gruntfile.js and updated the ngtemplates task to create a stand alone templates.js file instead of appending it into existing main.js. I don't even need the append: false
option but keeping it just for sake of it. Also changed the bootstrap:
option to use define
instead of require
ngtemplates: {
options: {
append: false,
bootstrap: function(module, script) {
return 'define([\'angular\', \'app\'], function(angular, app) { app.run([\'$templateCache\', function($templateCache) {' + script + '}]); });';
}
},
app: {
cwd: 'app',
src: '*/partials/*.html',
dest: 'app/templates.js'
}
},
I changed my routes.js (inserted below). Added the 'templates' module depenncy so that requirejs would load the templates.js and run it, which will execute the $templateCache.put()
code before it comes to return $templateCache.get()
line. And by that time the templcateCache will be ready. I also was doing a silly mistake by not using the same KEY to get the template which I was using to putting it in the templateCache. I had an extra app/
in front of the key while trying to pull it back from the templateCache.
define(['app', 'templates'], function(app) {
'use strict';
return app.config(function($stateProvider) {
var routes = [{
state: 'home',
url: '/home',
templateUrl: 'home/partials/home.html',
controller: 'homeController'
}];
$stateProvider.state(route.state, {
url: route.url,
// templateUrl: route.templateUrl,
templateProvider: function($templateCache) {
return $templateCache.get(route.templateUrl);
},
controller: route.controller,
params: route.params
});
after these changes, my build folder was ready to be used as expected.