I am bit new to angular js. Here I am trying to use angular js with require js. While configuring it I am getting a weird undefined error for $location while the error has not occurred for $scope.
main.js
require.config({
paths: {
'angular' : 'core/angular.min',
'uiRouter': 'core/angular-ui-router.min'
},
shim: {
uiRouter:{
deps: ['angular'],
exports: 'angular'
},
angular: {
exports : 'angular'
}
}
});
require(['app']);
app.js
(function (define){
"use strict";
define(
[
'angular',
'uiRouter',
'controllers/headerCtrl'
],
function (angular,uiRouter,headerCtrl) {
var app = angular.module('test', ["ui.router"]);
app.controller('headerCtrl',headerCtrl);
angular.bootstrap( document.getElementsByTagName("body")[0], [ 'test' ]);
return app;
}
);
}(define));
headerCtrl.js
(function( define ) {
"use strict";
define(
[],
function(){
var headerCtrl= function($scope, $location) {
console.log($location.path());
};
return ['$scope',headerCtrl];
}
);
}( define ));
Here when I am trying to get the path from $location its saying "$location" is undefined but $scope is accessible.
Please tell where am I going wrong here?
Related
I'm trying to migrate an application from Backbone to Marionette (v3), but I got stuck in a point for two days already.
When I try to run the app in browser, this error shows up in the console (and the screen is blank):
Uncaught SyntaxError: Unexpected token import in backbone.radio.js:1
First line in backbone.radio.js is the import statement for underscore:
import _ from 'underscore';
I use Requirejs as a module loader. This is the configuration in main.js:
require.config({
paths: {
jquery: '../bower_components/jquery/dist/jquery',
underscore: '../bower_components/underscore/underscore',
backbone: '../bower_components/backbone/backbone',
'backbone.radio': '../bower_components/backbone.radio/build/backbone.radio',
'backbone.babysitter': '../bower_components/backbone.babysitter/src/build/backbone.babysitter',
marionette: '../bower_components/marionette/lib/backbone.marionette',
bootstrap: '../bower_components/bootstrap/dist/js/bootstrap',
text: '../bower_components/requirejs-plugins/lib/text'
},
map: {
'*': {
'backbone.wreqr': 'backbone.radio'
}
},
shim: {
jquery: {
exports: '$'
},
underscore: {
exports: '_'
},
backbone: {
deps: [ 'underscore', 'jquery' ],
exports: 'Backbone'
},
marionette: {
deps: [ 'jquery', 'underscore', 'backbone' ],
exports: 'Marionette'
},
bootstrap: {
deps: [ 'jquery' ]
}
}
})
require(['appinstance'], function (app) {
app.start()
})
This is my appinstance.js:
define(function (require) {
var App = require('app')
return new App()
})
And this is my app.js file:
define(function (require) {
var $ = require('jquery')
var _ = require('underscore')
var Backbone = require('backbone')
var Router = require('router')
var Controller = require('controller')
var Marionette = require('marionette')
var CommonHeaderView = require('views/common/header')
return Marionette.Application.extend({
/**
* Define the regions for the application.
*
* #returns {Object}
*/
regions: function () {
return {
header: '#header'
}
},
/**
*
* #param {Object} options
*/
start: function (options) {
var commonHeaderView = new CommonHeaderView()
Marionette.Application.prototype.start.apply(this, [options])
this.header.show(commonHeaderView)
this.Router = new Router({ controller: new Controller() })
Backbone.history.start()
}
})
})
Does anyone know why I'm having this problem?
Unfortunately I ran out of ideas on how to solve this, any help will be greatly appreciated.
P.S.: I use Marionette v3.0.0, Backbone v1.2.3 and Requirejs v2.1.15
That it complains about an import-statement is an indication that you are referencing a source file. Make sure your backbone.radio-path goes to the build file.
I struggling with understanding why I'm seeing several "No define call for" when attempting to load my angular application. Well I know they are there because I'm using enforeDefine: true, but what is wrong with my code? What do I need to do to satisfy the enforceDefine?
Errors:
main.js
/*global require, requirejs */
'use strict';
requirejs.config({
enforceDefine: true,
paths: {
angular: ['//cdn.jsdelivr.net/webjars/org.webjars/angularjs/1.4.0/angular.min','../lib/angularjs/angular.min'],
'angular-messages': ['//cdn.jsdelivr.net/webjars/org.webjars/angularjs/1.4.0/angular-messages.min','../lib/angularjs/angular-messages.min'],
'angular-resource': ['//cdn.jsdelivr.net/webjars/org.webjars/angularjs/1.4.0/angular-resource.min','../lib/angularjs/angular-resource.min'],
'angular-ui-bootstrap': ['//cdn.jsdelivr.net/webjars/org.webjars/angular-ui-bootstrap/0.13.0/ui-bootstrap-tpls.min','../lib/angular-ui-bootstrap/ui-bootstrap-tpls.min'],
uiRouter: ['//cdn.jsdelivr.net/webjars/org.webjars/angular-ui-router/0.2.15/angular-ui-router.min','../lib/angular-ui-router/angular-ui-router.min'],
bootstrap: ['//cdn.jsdelivr.net/webjars/org.webjars/bootstrap/3.3.4/bootstrap.min','../lib/bootstrap/js/bootstrap.min'],
jquery: ['//cdn.jsdelivr.net/webjars/org.webjars/jquery/2.1.4/jquery.min','../lib/jquery/jquery.min'],
async: '../lib/requirejs-plugins/src/async'
},
shim: {
angular: {
exports : 'angular'
},
uiRouter: {
deps: ['angular']
},
'angular-ui-bootstrap': {
deps: ['angular']
},
'angular-resource': {
deps: ['angular']
},
'angular-messages': {
deps: ['angular']
},
bootstrap: {
deps: ['jquery'],
exports: 'jQuery.fn.popover'
}
},
deps: ['app']
});
app.js
/*global require, requirejs */
'use strict';
define(['angular',
'./controllers',
'./directives',
'./filters',
'./services',
'bootstrap',
'jquery',
'uiRouter',
'angular-ui-bootstrap',
'angular-messages',
'angular-resource',
'async',
'./gmaps'
],
function(angular, controllers) {
// Declare app level module which depends on filters, and services
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ui.router', 'ngMessages','ngResource','ui.bootstrap']).
config(['$stateProvider','$urlRouterProvider','$httpProvider', function($stateProvider, $urlRouterProvider, $httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$urlRouterProvider.otherwise('/home');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
.... several routes here that I hid
});
}]).controller('RouteCtrl', ['$scope','$state', function($scope, $state) {
$scope.$state = $state;
}]);
angular.bootstrap(document, ['myApp']);
});
From this (emphasis mine):
enforceDefine: If set to true, an error will be thrown if a script loads that does not call define() or have a shim exports string value that can be checked.
So the script loaded must either comply with AMD (Angular doesn't) or define an exports in its shim configuration.
Since main is yours, just make it a proper AMD module. The "problem" is that the other scripts (uiRouter, angular-ui-bootstrap, angular-resource, angular-messages) do not actually export anything. My suggestion is just re-export angular (or any other global, e.g. document, but angular seems more relevant) so that you satisfy RequireJS:
requirejs.config({
...
'angular-resource': {
deps: ['angular'],
exports: 'angular'
}, // and so on...
...
});
This is a bypass, but I do not think there is any other way, if you insist on using enforceDefine.
You might need to change the require inside the script you specify as being data-main to be a define instead. There has been a issue on GitHub noted that sounds similar to what you are running into.
The library author suggests that if you use the enforceDefine flag then your data-main module should also use a define.
I'm starting off with an empty body element and then dynamically adding HTML that contains an ng-controller attribute. I want to bootstrap the Angular application after that html has been added to the body . This works fine with angular 1.0 but not with 1.3.8. Any ideas why?
require(['angular'], function(angular){
'use strict';
buildDom();
function buildDom(){
$('body').append('<div role="tabpanel" ng-controller="WelcomeController"><span>{{greeting}}</span></div>');
}
var app = angular.module('demo', []);
app.controller('WelcomeController', function($scope) {
$scope.greeting = 'Welcome!';
});
angular.element(document).ready(function() {
angular.bootstrap(document, ["demo"]);
});
});
end result - I see {{greeting}} and not Welcome!
right way of bootstrapping angularjs and requirejs is something like:
'use strict';
require.config({
baseUrl: 'js/',
deps: ['jquery'],
paths: {
jquery: '../lib/jquery.min',
angular: '../lib/angular.min'
},
shim: {
'angular': {
'deps': ['jquery'],
'exports': 'angular'
}
},
priority: [
'angular'
]
});
//https://docs.angularjs.org/guide/bootstrap
window.name = 'NG_DEFER_BOOTSTRAP!';
require([
'angular',
'app'
], function(angular, app) {
'use strict';
var $html = angular.element(document.getElementsByTagName('html')[0]);
angular.element().ready(function() {
angular.resumeBootstrap([app['name']]);
});
});
now you should have a separate file called app.js :
define([
'angular',
'services',
'directives',
'controllers'
], function (angular) {
'use strict';
return angular.module('myapp', [
'myapp.services',
'myapp.directives',
'myapp.controllers'
]);
});
Then you should have on each file (services.js, directives.js and controllers.js) each one of your angular components declared.
I am trying to work on an Angular application powered by RequireJS, but I am not able to split up the controller files as I keep getting an error of Argument '(contoller)' is not a function, got undefined. Any idea what have I done wrong?
app/main.js,
require.config({
baseUrl: "",
// alias libraries paths. Must set 'angular'
paths: {
'domReady': 'bower_components/requirejs-domready/domReady',
'angular': 'bower_components/angular/angular',
'angular-route': 'bower_components/angular-route/angular-route',
'jquery': 'bower_components/jquery/dist/jquery'
},
// Add angular modules that does not support AMD out of the box, put it in a shim
shim: {
'angular': {
exports: 'angular'
},
'angular-route': {
exports: 'angular'
}
},
// kick start application
deps: ['app/bootstrap']
});
app/app.js,
define([
'angular',
'angular-route',
'jquery'
], function (ng,ngRoute,$) {
'use strict';
console.log($('h1').length);
return ng.module('app', ['ngRoute']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/home', {
templateUrl: 'view/home.html',
controller: 'HomeCtrl',
controllerUrl: 'app/home'
});
$routeProvider.when('/view1', {
templateUrl: 'view/view1.html',
controller: 'View1Ctrl',
controllerUrl: 'app/view'
});
//$routeProvider.otherwise({redirectTo: '/home'});
}]);
});
app/home.js,
define(['app/app'], function (app) {
app.controller('HomeCtrl', function ($scope) {
$scope.message = "Message from HomeCtrl";
});
});
error,
Error: [ng:areq] Argument 'HomeCtrl' is not a function, got undefined
But if I concat the controllers after ng.module('app', ['ngRoute']).config(...) then they work fine,
app/app.js,
define([
'angular',
'angular-route',
'jquery'
], function (ng,ngRoute,$) {
'use strict';
console.log($('h1').length);
return ng.module('app', ['ngRoute']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/home', {
templateUrl: 'view/home.html',
controller: 'HomeCtrl',
//controllerUrl: 'app/home'
});
$routeProvider.when('/view1', {
templateUrl: 'view/view1.html',
controller: 'View1Ctrl',
//controllerUrl: 'app/view'
});
//$routeProvider.otherwise({redirectTo: '/home'});
}]).controller('HomeCtrl', function ($scope) {
$scope.message = "Message from HomeCtrl";
}).controller('View1Ctrl', function ($scope) {
$scope.message = "Message from View1Ctrl";
});
});
Why??
This seems to be a problem with the load order of your JS files. You are defining the HomeCtrl in app/home.js and using it it app/app.js. So make sure that home.js is loaded before app.js in your web app.
Split the app.js into two parts - one for just creating the ng.module (module.js), and one for setting the config (module-config.js). Then the dependency tree will be:
app/module-config.js
requires: app/home.js
requires: app/module.js
I load AngularJs and jQuery using RequireJs in nodeJs framework.
That is main.js
require.config({
paths: {
angular: 'vendor/angular.min',
bootstrap: 'vendor/twitter/bootstrap',
jquery: 'vendor/jquery-1.9.0.min',
domReady: 'vendor/require/domReady',
underscore: 'vendor/underscore.min'
},
shim: {
angular: {
deps: [ 'jquery' ],
exports: 'angular'
}
}
});
require([
'app',
'angular-boot'
], function() {
});
in app.js
define(['angular'], function (angular) {
return angular.module('MyApp', []);
})
and in angular-boot.js
define([ 'angular', 'domReady' ], function (angular, domReady) {
domReady(function() {
angular.bootstrap(document, ['MyApp']);
});
});
In my html file I have only this line, in order to declare and use requirejs.
Not ng-ap or anything else.
<script data-main="js/main" src="js/require.js"></script>
The problem is that sometimes runs, sometimes not.
The error when it doesn't run is
Uncaught Error: No module: MyApp
If there is any thought about it, I would really appreciate it.
Thank you very much.
In your shim, you need to setup the app as a dependency to angular-boot. Your angular-boot file depends on app (where MyApp is defined), and because the load order for these two files is not specified, sometimes angular-boot loads before the app and thus produces that error.
To remedy, just update your shim as such:
shim: {
angular: {
deps: [ 'jquery' ],
exports: 'angular'
},
'angular-boot': {
deps: ['app']
}
}
and than, since you don't need to include the 'app' explicitly your require call can be reduced to:
require(['angular-boot']);