Getting Angularjs with Requirejs working with restangular and twitter bootstrap - angularjs

I am building a new angularjs app and want to use requirejs to manage my dependencies. I am struggling to get this to work and wonder if I'm just misunderstanding something. I also want to use twitter bootstrap and restangular to make restful calls. Trying to set this up leads to errors of not being able to find it. My main,js config is as follows:
require.config({
paths: {
angular: '../vendor/angular',
twitterbootstrap: '../vendor/bootstrap/ui-bootstrap-tpls-0.6.0',
restangular: '../vendor/restangular',
domReady: '../vendor/domReady'
},
shim: {
angular : {'exports' : 'angular'},
restangular: {
deps: ['underscore']
}
}
});
require([
'angular',
'app',
'domReady',
'twitterbootstrap',
//'underscore',
'restangular',
],
function (angular, app, domReady) {}...
I am getting errors with this:
angular is not defined
no module myApp
no module twitterbootstrap
I have tried several variations with this but just can't get it to play nicely together. Is there something else I'm missing - I've compared it to several examples and everything seems to be in order.

Mixing Angular and Require is tricky. I have an experimental project in GitHub (https://github.com/nikospara/angular-require-lazy) that works in some hacky way. You may take a look as an example.
Opinions comments on this project are also wellcome.
For your errors:
Open a net console (e.g. in Firebug) and check the paths called by RequireJS. Are these paths correct?
Angular modules (in contrast to Require/AMD modules) have dependencies of their own. You must make sure that .js files of Angular modules are loaded after angular. One way to do that is to shim them, e.g. for restangular it would be something like:
shim: {
...
restangular: {
deps: ["underscore", "angular"]
}
}
Otherwise you can load angular and the other scripts with standard <script> tags, in the correct order.
These are general directions. If you can't find the reason of the problems, maybe you should post some more code; a fiddle/plunkr would also be great, if possible.
Related post in SO: Inject module dynamically, only if required

Related

How can I pre load a template in Angular UI router?

I am using Angular UI router. I have many template calls like this:
var access = {
name: 'access',
templateUrl: 'app/access/partials/a1.html',
};
The page served by Access depends on the :content.
Is there a way that I could combine all these HTML files into one and pre-load the files so every action didn't involve another request? I realized I can put my HTML directly inside the template but can I combine the HTML from multiple templates into one file and have it all pre-loaded so it's ready when needed?
Is there a way that I could combine all these HTML files into one and pre-load the files so every action didn't involve another request?
Yes, by using html2js;
or, to be exact, a grunt/gulp plugin called, respectively, grunt-html2js / gulp-html2js
HOW IT WORKS
According to this grunt-html2js tutorial:
" html2js is a plugin (...) that parses all template files in your application and creates a javascript file that populates the $templateCache.
This is very useful trick to reduce the number of request your app needs to make to start the application.
It can also minify the html snippets saving some bandwitdh as well."
----------
According to the grunt-html2s Github repository:
"html2js converts a group of templates to JavaScript and assembles them into an Angular module that primes the cache directly when the module is loaded.
You can concatenate this module with your main application code so that Angular does not need to make any additional server requests to initialize the application."
----------
And according to me :)
What I like about html2js is that you don't need to change any of your angular code, but just configure gruntfile.js / gulpfile.js.
Your templateUrl files will then automagically be available in $templateCache.
So it does exactly what you wished for:
Combine all your templates into a module;
Write the JavaScript source for the module;
All you need to do is to specify the module as a dependency in your code.
Once the module is loaded, all your templates are available in the cache: no request needed!
EXAMPLES OF GRUNT / GULP CONFIG
grunt.initConfig({
html2js: {
options: {
base: 'app',
module: 'templates',
htmlmin: {
... many available options: see GitHub repo ...
}
},
main: {
src: ['app/**/*.html'],
dest: 'templates.js'
},
},
})
then just use the templates module as a dependency:
angular.module('myApp', [ 'templates']);
----------
Here is an example from the gulp-html2js GitHub repository:
gulp.task('scripts', function() {
gulp.src('fixtures/*.html')
.pipe(html2js({
outputModuleName: 'template-test',
useStrict: true
}))
.pipe(concat('template.js'))
.pipe(gulp.dest('./'))
})
TESTING
What's more, html2js is also a very good tool to test directives that use the templateUrl property.
FOR MORE INFORMATION
I came accross html2js after reading Joel Hooks' (Egghead instructor) book about automation, which I strongly recommend.
Watch a dedicated video about html2js in the pro section of the EggHead website.
Testing directives using the templateUrl property with Karma and karma-ng-html2js-preprocessor
NOTE
Technically, you could just use ng-html2js, without using Gulp or Grub; you could then use a command line like the following:
ng-html2js inputFile [outputFile] [-m moduleName] [--module-var ngModule]
However, as you would need to run the above command for each templateUrl file, Gulp/Grub automation seems to be a more efficient way to go.
DISCLAIMER
I have no particular interest or shares in the book/websites/tools I mentioned.
Note: I should also add, you also add this file to your html page:
<script src="path/to/templates.js"></script>
Why not use ng-include in your main html file to load all html's at once.
Something like this...
<div ng-repeat="template in templates">
<ng-include src="template.url"></ng-include>
</div>
So here templates is an array of objects which contains all the url's the other templates which you want to load at once in your main.html file.
Easy. Create them all as ng-template blocks:
<script type="text/ng-template" id="app/access/partials/a1.html">
Content of the template.
</script>
There is already a grunt-angular-templates grunt plugin specific to this angular task only. i have been using it for a while now. this plugin automatically caches your HTML templates using $templateCache in one file which you can add in your application.
grunt-angular-templates - https://www.npmjs.com/package/grunt-angular-templates
Use,
yourApp.run(['$templateCache', function($templateCache) {
$templateCache.removeAll();
}])
Your problem pointed in this site too,
http://javahow.net/questions/27321315/using-angulars-ui-router-how-can-we-make-sure-the-new-version-of-the-html-part

creating a ydn-db service for angularjs

I'm working on a project using Meanjs and ydn-db for indexeddb support.
So I'm trying to make a service in angular, but I just can't figure a way to include the js file properly. I've tried installing the lib in the following methods:
bower install ydn-db
bower install ydndb
The first case, I could not find a suitable.js file like ydn.db-isw-core-qry-dev.js. Now the second would install the two minified versions which I could work, but I always get the ydn not found error
Now by looking into the Developer's page http://dev.yathit.com/ydn-db/getting-started.html I can see that he has a way of making the require in the AMD loader section, which I simply did not know how to use inside the service factory.
Here is what I'm trying to do inside the factory which by the way I don't think is best practices...
And these are the error that I'm getting just by trying to load this...
How can I use this lib while still following best practices for angular or at least just to get it working without errors?
ldb undefined
Object {db: Object, debug: Object}
Uncaught ydn.error.ArgumentException: Unknown attribute "keypath"
angular.module(ApplicationConfiguration.applicationModuleName).factory('Localdb',['$resource','$q',
function($resource,$q) {
var deferred=$q.defer();
require.config({
baseUrl: '/content',
paths: {
ydn: 'scripts/ydn.db-isw-core-qry-dev'
}
});
require(['scripts/ydn.db-isw-core-qry-dev'], function(ldb){
console.log ('ldb',ldb);//this is undefined
var schema ={
stores:[
{
name:'process',
keypath:'_id',
indexes:[{
name:'processId',
keypath:'processId',
unique:false
},{
name:'processMeta',
keypath:'processMeta',
unique:false
}
]
}
]
};
console.log(ydn);//this gets back ok but then the keypath error???
deferred.resolve(new ydn.db.Storage('pdc',schema));
});
return deferred.promise;
}
]);
Sorry, to get your trouble. ydn-db repo do not have compiled js file, as require (I think) by bower. So it doesn't work. Just download one of the js file and add to your html.
Also check out ydn-db with angular example app.

Grunt.js for Angular.js dependency injection management

I am using Grunt to automatically build my web app. I have run into an interesting issue. I have two options: 1)grunt:dev and 2)grunt:build
grunt:dev just does basic tasks related to development. My "main" Angular module looks like this:
var myApp= angular.module('myApp', [
"ui.router",
"ui.bootstrap",
"someDependency",
"someDependency2"
]);
When I want to build, I do grunt:build. I am using the html2js grunt plugin to prime the Angular cache. However, this method generates a new module not in my development workflow called templates-main.
In order for this to work, when I build, I need the "main" module to look like:
var myApp= angular.module('myApp', [
"ui.router",
"ui.bootstrap",
"templates-main", //<<< NEW DEPENDENCY
"someDependency",
"someDependency2"
]);
Is there a recommended way of accomplishing this? If you include the dependency, but it is not there, it causes an Angular error. I am hoping this can be automated with Grunt.
Thanks in advance
I figured out a workaround for this. I am using Grunt's Concat module. This allows you to have a custom process system with regular expressions:
build: {
options: {
process: function(src, filepath) {
return src.replace(/[/*<%]{4}.*[%>*/]{4}/g, '"templates-main",');
}
},
src: ['src/app/app.js', 'src/app/**/*.js'],
dest: 'build/app.js'
}
I then did the following in the code:
var eeApp = angular.module('eeApp', [
"ui.router",
"ui.bootstrap",
/*<% templates-main %>*/
"dashboard"
]);
In normal use, the block comment will prevent the code from throwing an error. When the template process goes through, the regular expression will match the entire comment block and substitute in the required dependency. Nice!
I think the easiest way is to create an empty fake module file for your dev build and overwrite it with the real template cache in the production build.
This way you shouldn't change the dependencies dynamically.
(Or you can copy this file with grunt as well in the development setup, if you wouldn't like to overwrite originals.)

Sails.js + RequireJS configuration

Having all kinds of problems getting Sails to work with RequireJS, mainly because I can't find any definitive source on the best way to do this. There are several posts out there that discuss this, but they are older and all do things differently. Would really love to see the Creators enlighten the community on the proper way to do this given the changes to the Sails application structure, linker process etc. in the latter versions (.0.9.9, ,0.10)
So, first question would be...if I am planning on using an AMD/RequireJS + Backbone approach for my client-side code, and want to use the R.js Optimizer in grunt to build my production JS file and resolve all the nested dependencies automatically (rather than have to list them out manually), should I not create the application with the --linker option and manually manage the grunt build process myself?
Also, where in the directory structure should the "vendor" directory be placed that contains all the dependent JS libs like Underscore, jQuery, Backbone etc. reside?
I decided this problem:
Install the plugin for grunt-requirejs
wrote config to run build in a folder /tasks/config/requirejs.js
Example:
module.exports = function(grunt) {
grunt.config.set('requirejs', {
dev: {
options: {
baseUrl: "assets/",
name: 'main',
optimize: "uglify2",//'none',//"uglify2",
//wrap: true,
paths: {
// Major libraries
jquery: '../vendor/jquery',
underscore: '../vendor/underscore',
backbone: '../vendor/backbone',
// Require.js plugins
},
removeCombined: true,
inlineText: true,
useStrict: true,
out: "build/main.js",
waitSeconds: 200
},
}
});
grunt.loadNpmTasks('grunt-contrib-requirejs');
};
added to autostart in tasks/register/compileAssets.js
Example:
module.exports = function (grunt) {
grunt.registerTask('compileAssets', [
'clean:dev',
'jst:dev',
'less:dev',
'copy:dev',
'coffee:dev',
'requirejs:dev'
]);
};
You also have to adjust just grunt at yourself and do not be afraid to change anything. At design time, better to store scripts in the Assets folder because it is convenient.
For others having the same problem, a quick but only partial fix is to disable the script injection by removing the following from layout.ejs:
<!-- SCRIPTS -->
<!-- SCRIPTS END -->
Then just place direct links to your require.js file:
<script src="/linker/js/components/requirejs/require.js"></script>
I say this is only a partial fix because the GruntFile will need need to implement a require task in order to concatenate the files correctly.

Can you use AngularJS's plugins with "enforceDefine" on RequireJS's shims?

So in the shim config of RequireJS, you can identify an "export" string option. This works for things that exports globals. However how do you do this for angular-resource or angular-cookies?
For jQuery plugins, you just find the relevant jquery object. But this does not work for AngularJS when I have "enforceDefine" enabled.
I've tried exports: "angular.module('ngResource')" but it didn't work either.
Inside the source code of angular-resource, it just adds things to the angular.module.
I ended up just exporting the "angular" global object.

Resources