Integrating AngularJS with RequireJS - javascript

Due This Article I try to create an application with AngularJS and RequireJS!
I can load angular library... create module and export it to external files! It's ok!
But the problem is I can't create configuration and controllers for my module both in main application file and external files!
Another issue is I can't load views and controllers in app.js via $routeProvider!!
(Sorry for grammer problems!)
app.js:
require.config({
baseUrl: "/angularjs/js",
paths: {
"angular": "libs/angular.min"
},
shim: {
"angular": {
exports: "angular"
}
}
});
define('app', ['angular'], function(angular){
var app = angular.module('myApp', []);
app.config(function($routeProvider, $locationProvider){
$routeProvider
.when('/', {
controller: 'HomeCtrl'
templateUrl: 'views/home.html'
});
});
return app;
});
require(["app", "controllers/homeController"]);
controllers/homeController.js:
require(["app"], function(app) {
app.controller("HomeCtrl",
function($scope) {
$scope.message = "Hello World!";
}
);
});
index.html:
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8" />
<title>Angular.js</title>
<script type="text/javascript" data-main="js/" src="js/libs/require.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
views/home.html:
<div ng-controller="HomeCtrl">
<h1>{{messge}}</h1>
</div>

Here is my version of your example. With a few changes it works fine.
It is better to bootstrap AngularJs application manually, when RequireJs.
I separated app.js file in two: main.js - with configuration of RequireJs and app.js - with AngularJs module declaration. Later, this module is used by homeController for declaration of controller. Then, the controller is required in main.js and the application is bootstrapping.

I do the angular and requireJS integration placing NG_DEFER_BOOTSTRAP! flag and have separate files for my app config and routing like in:
require.config({
baseUrl: 'js/',
paths: {
angular: '../lib/bower_components/angular/angular.min',
angularRoute: '../lib/bower_components/angular-route/angular-route.min'
},
shim: {
'angular': {
'exports': 'angular'
},
'angularRoute':{
'deps': ['angular']
}
},
priority: [
'angular'
]
});
//https://docs.angularjs.org/guide/bootstrap
window.name = 'NG_DEFER_BOOTSTRAP!';
require([
'angular',
'app',
'routes'
], function(angular, app, routes) {
'use strict';
var $html = angular.element(document.getElementsByTagName('html')[0]);
angular.element().ready(function() {
angular.resumeBootstrap([app['name']]);
});
});
app.js:
define([
'angular',
'filters',
'services',
'directives',
'controllers',
'animations',
'angularRoute'
], function (angular) {
'use strict';
return angular.module('myapp', [
'ngRoute',
'ngCookies',
'ngAnimate',
'myapp.services',
'myapp.directives',
'myapp.filters',
'myapp.controllers',
'myapp.animations'
]);
});
and routes.js:
define(['angular', 'app'], function(angular, app) {
'use strict';
return app.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/home', {
templateUrl: 'partials/home.html',
controller: 'HomeCtrl'
}).
when('/login', {
templateUrl: 'partials/login.html',
controller: 'LoginCtrl'
}).
otherwise({
redirectTo: '/home'
});
}])
});
hope this helps in your scenario.

Related

AngularJS controller does not run on RequireJS config

I am trying to configure an web app with requireJS and angularJS. I come from marionette configuration and I am trying to have a similar one in angular (in concepts like views and controllers) first so I want to be able to map #/test to my controller and log in the console one message.
I've seen Does AngularJS support AMD like RequireJS? and RequireJS and AngularJS and I kind of got the differences and from my point of view my config should work... but it does not...
Here is my code:
File: app.config.js
require.config({
shim: {
angular: {
exports: 'angular'
},
angularRoute: ['angular']
},
paths: {
angular: '../lib/angular',
angularRoute: '../lib/angular-route'
}
});
require(['angular', 'app', 'routes/index'], function (angular) {
angular.bootstrap(document, ['app']);
});
File: app.js
define(['angular', 'angularRoute'], function (angular) {
//angular.module('app.controllers', []);
var app = angular.module('app', ['ngRoute']);
return app;
});
File: routes/index.js
define(['angular', 'app', 'controllers/index'], function (angular, app) {
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', { templateUrl: require.toUrl('/resources/js/app/templates/test.html'), controller: 'indexController'});
}]);
});
File: controllers/index.js
define(['angular', 'app'], function (angular, app) {
//var appControllers = angular.module('app.controllers');
app.controller('indexController', ['$scope', function ($scope) {
console.log('cascade...');
}]);
});
What am i missing? When i access #/test, i don't see "cascade" in the console, should I?.. Right?
Thanks in advance.

Access templates from $templateCache in $routeProvider

Am new to Angular JS and trying to implement grunt-angular-templates. I have successfully concatenated all htmls's into one JS file.
My app.js file:
angular.module('LoginApp').config(function ($routeProvider
.when('/login', {
templateUrl: '/views/common/login.html',
controller: 'LoginCtrl'
})
.otherwise({
redirectTo: '/account'
});
);
So from here if i load http://localhost:50/login, i can see login page on the screen and referred from /views/common/login.html path.
I am trying to implement the same using $templateCache. I have all the htmls concatenated in a JS file. I need to refer templates from the common JS file. I have included the template JS file in the index.html
Concatenated JS file:
angular.module('LoginApp').run(["$templateCache", function($templateCache) {
$templateCache.put("../app/views/commmon/login.html",
// contents for login.html ...
);
}]);
My Gruntfile
ngtemplates: {
myapp: {
options: {
base: "web",
module: "LoginApp",
},
src: ['app/views/common/*.html'],
dest: 'dist/views/html.js'
}
},
How can i access/refer templates from $templateCache?
TIA
You don't have to use $templateCache manually. If your template is cached, Angular is going to load it automatically.
The templateUrl should be the ID of your cached template generated by Grunt.
See this Plunker http://plnkr.co/edit/132S5UMLnBzzGGGI85l3
index.html
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-route.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-view></div>
<script type="text/ng-template" id="login.html">
login.html
</script>
<script type="text/ng-template" id="account.html">
account.html
</script>
</body>
</html>
script.js
'use strict';
angular.module('sandbox', [
'ngRoute'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/login', {
templateUrl: 'login.html'
})
.otherwise({
redirectTo: '/login'
});
}]);

AngularJs $injector:modulerr after RequireJS r.js optimization

The AngularJS-RequireJS app im building is throwing Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:unpr] Unknown provider: e error after r.js optimization . The problem didnt exist before . I followed a similar question at this link and added mainConfigFile to the build file , but still the problem persists . Here are the codes the respective files
build.js
({
mainConfigFile:'js/main.js',
appDir: "./",
baseUrl: "js",
dir: "/home/karthic/optimized-test",
modules: [
{
name: "main"
}
]
})
main.js
require.config({
baseUrl: './js',
paths: {
angular: 'libs/angular-1.2.9',
angularRoute: 'libs/angular-route-1.2.9'
},
shim: {
'angularRoute': {
deps: ['angular'],
exports: 'angularRoute'
},
'angular': {
exports: 'angular'
}
}
});
require(['angular', 'controller', 'ang_when_routes', 'angularRoute'], function(angular, controller, angWhenRoutes, angularRoute) {
'use strict';
var app = angular.module('myApp', ['ngRoute']);
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
angWhenRoutes.initRoutes(app);
controller.controllerInit(app);
});
controller.js
define(function() {
function controllerInit(app) {
console.log('inside func cont');
app.controller('mapApp', function($scope, $http, $location) {
console.log('inside mapp,testing r.js optimizer');
});
}
return {
controllerInit: controllerInit
}
});
ang_when_routes.js
define(function() {
function initRoutes(app) {
app.config(
function($routeProvider, $httpProvider) {
$httpProvider.defaults.withCredentials = true;
$routeProvider.
when('/', {
templateUrl: 'index_content.html',
controller: 'mapApp'
})
});
}
return {
initRoutes: initRoutes
}
});
index.html
<!DOCTYPE html>
<html>
<head>
<title>Optimizer error</title>
<script data-main="js/main.js" src="js/libs/require.js"></script>
</head>
<body>
<div ng-view>
</div>
</body>
</html>
index_content.html
<p>Testing the r optimizer</p>
It'll be really helpful for me if the error can be fixed
Here is the answer as suggested by #radimKohler in the first comment . To avoid issues with angularJS during minification Inline array Annotation has to be used as referred in the Angular Documentation . Here is the modified code after the change
controller.js
define( function () {
function controllerInit(app) {
console.log('inside func cont');
app.controller('mapApp',['$scope','$http','$location', function ($scope, $http, $location) {
console.log('inside mapp,testing r.js optimizer');
}]);
}
return {
controllerInit: controllerInit
}
});
ang_when_routes.js
define(function(){
function initRoutes(app){
app.config(['$routeProvider','$httpProvider',
function($routeProvider,$httpProvider){
$httpProvider.defaults.withCredentials = true;
$routeProvider.
when('/',{
templateUrl:'index_content.html',
controller:'mapApp'
})
}]);
}
return {
initRoutes:initRoutes
}
});

AngularJS 1.2.9 ngRoute "unknown provider $routeProvider error with requireJS

I'm using angularJS-1.2.9 and angular-route-1.2.9 to set up routes for my application , i'm using requireJS as the dependency loader and modularize the code . I have added the ngRoute dependency into the AngularJS config , but still getting this following error in the chrome console Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:Error: [$injector:unpr] Unknown provider: $routeProvoider
Here is my code
main.js
require.config({
baseUrl: './js',
paths: {
angular: 'libs/angular-1.2.9',
angularRoute: 'libs/angular-route-1.2.9'
},
shim: {
'angularRoute': {
deps: ['angular'],
exports: 'angularRoute'
},
'angular': {
exports: 'angular'
}
}
});
require(['angular', 'angularRoute'], function (angular, angularRoute) {
'use strict';
var app = angular.module('myApp', ['ngRoute']);
angular.element(document).ready(function () {
angular.bootstrap(document, ['myApp']);
});
app.controller('indexController', function ($scope, $http) {
console.log('inside index');
});
app.config(
function ($routeProvoider) {
$routeProvider.
when('/', {
templateUrl: 'index_content.html',
controller: 'indexController'
})
});
});
Here are my html files
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<script data-main="js/main.js" src="js/libs/require.js"></script>
</head>
<body>
<div ng-view>
</div>
</body>
</html>
index_content.html
<p>inside Index content</p>
<h1>testing the ang routes
Whats the issue here ?? Why is it still giving away the above mentioned error ?? How to fix this ??
There is a typo error on $routeProvider in the code I have rectified and placed the code below:
Code Snippet:
require(['angular', 'angularRoute'], function (angular, angularRoute) {
'use strict';
var app = angular.module('myApp', ['ngRoute']);
angular.element(document).ready(function () {
angular.bootstrap(document, ['myApp']);
});
app.controller('indexController', function ($scope, $http) {
console.log('inside index');
});
app.config(
function ($routeProvider) { //One typo here
$routeProvider.
when('/', {
templateUrl: 'index_content.html',
controller: 'indexController'
})
});
});
app.config(
function ($routeProvider) {
$routeProvider.
when('/ResourceItem/:RE_RestoId',{
templateUrl:'./partials/state-view.html',
controller: function ($routeParams, ResourceService) {
this.params = $routeParams;
var that = this;
ResourceService.getResourceItem(this.params.RE_RestoId || "").success(function (data) {
that.items = data;
})
this.addItemTo = function (resource)
{
if(!resource.items)
{
resource.items = [];
}
resource.items.push({TA_Code: this.newResourceItem });
this.newResourceItem="";
};
},
controllerAs:'ResourceItemCtrl'
});
});

How to Require Angular Controllers

Im new to Angularjs and i am trying to integrate with my application that uses RequireJS. I have the application working on a test page using the ng-submit. However, in my app.js file i dont think i am "require"ing my controllers in the best way.
I am using AngularJS v1.1.5
Here's my tree:
resources
- CSS
- js
- controllers
- TestController1.js
- TestController2.js
- TestController3.js
- TestController4.js
- TestController5.js
- libs
- angular.js
- jquery.js
- require.js
- mondernizr.js
......
......
......
main.js
app.js
pages
test1.html
test2.html
test3.html
test4.html
test5.html
main.js
(function(require) {
'use strict';
require.config({
baseUrl: '/libs',
paths: {
'zepto' : 'zepto',
'jquery' : 'jquery',
'angular' : 'angular',
'router' : 'page',
'history' : 'history.iegte8',
'event' : 'eventemitter2'
},
shim: {
'zepto' : { exports: '$' },
'angular' : { deps: ['jquery'], exports: 'angular' },
'app' : { deps: ['angular'] },
'router' : { exports: 'page'},
'modernizr' : { exports: 'Modernizr' }
}
});
require(['angular', 'app'], function(angular) {
'use strict';
angular.bootstrap(document, ['app']);
});
})(this.require);
app.js
define("app", ["angular"], function(angular){
var app = angular.module("app", []);
app.config(function($routeProvider, $locationProvider){
$routeProvider
.when("/test1", {
templateUrl: "test1.html",
controller: "TestController1"
})
.when("/test2", {
templateUrl: "test2.html",
controller: "TestController2"
})
.when("/test3", {
templateUrl: "test3.html",
controller: "TestController3"
})
.when("/test4", {
templateUrl: "test4.html",
controller: "TestController4"
})
.when("/test5", {
templateUrl: "test5.html",
controller: "TestController5"
})
.otherwise({ redirectTo: '/test1'});
});
return app;
});
require(["app", "controllers/TestController1"]);
require(["app", "controllers/TestController2"]);
require(["app", "controllers/TestController3"]);
require(["app", "controllers/TestController4"]);
require(["app", "controllers/TestController5"]);
TestController1-5.js
require(['app'], function(app) {
app.controller("TestController1", function($scope) {
$scope.clickMe = function() {
alert('TestController1.js is responding');
$scope.title = "Title";
$scope.data = {message: "Hello"};
$scope.message = "Hello World!";
};
});
});
test1-5.html
<div ng-controller="TestController1">
<form ng-submit="clickMe()">
<div>
<button type="submit">Test TestController1</button>
</div>
</form>
{{ data.message + " world" }}
{{ title }}
</div>
Equally if you think there are other ways i can improve my code and code structure feel free to suggest.
Thanks
Maybe you could just improve your code by making an "app.controllers" module that will be in charge of loading all your controllers. Then in your app.js, you just add this module as dependency.
So for instance.
app/controllers/MyController.js:
define(['angular'], function(angular) {
return angular.module('app.controllers.MyCtrl', [])
.controller('MyCtrl', [function(){
[...]
}]);
app/controllers.js:
define([
'angular',
'app/controllers/MyController'
],
function(angular) {
return angular.module('app.controllers', [
'app.controllers.MyCtrl'
]);
});
app/app.js:
define("app", "app/controllers", ["angular"], function(angular){
var app = angular.module("app", ['app.controllers']);
app.config(function($routeProvider, $locationProvider){
$routeProvider
.when("/my", {
templateUrl: "my.html",
controller: "MyCtrl"
})
.otherwise({ redirectTo: '/test1'});
});
return app;
});
You could also load controllers asynchronously this way for instance:
angular.module('myApp.controllers', [])
.controller('MyCtrl', ['$scope','$injector', function($scope, $injector){
require(['app/controllers/MyController'], function(MyCtrl){
$injector.invoke(MyCtrl, this,{'$scope':$scope});
});
}]);
The downpoint of this kind of loading is that you will have to manually call $scope.$apply(); in order to manually ask for a digest otherwise your scope modifications on this controller will not be taken into account as it is with "standard" loading.
However, I will not recommend this kind of loading. In the end when the code is minified and optimized in one file with r.js, it does not make much sense to "lazy load" code.

Categories