I'm trying to set up my angularjs app using AngularAMD (a Requirejs implementation with AngularJs), but sometimes i get
Cannot read property 'bootstrap' of undefined(…)
main.js
require.config({
paths: {
//Angular
'angular': '/bower_components/angular/angular',
'angular-route': '/bower_components/angular-route/angular-route.min',
'angularAMD': '/bower_components/angularAMD/angularAMD.min',
'angular-slick': '/bower_components/angular-slick/dist/slick.min',
'angular-sanitize': '/bower_components/angular-sanitize/angular-sanitize',
//Plugins
'jquery': '/bower_components/jquery/dist/jquery',
'materialize': '/bower_components/Materialize/dist/js/materialize.min',
'jquery-hammer': '/bower_components/Materialize/js/jquery.hammer',
'hammerjs': '/bower_components/Materialize/js/hammer.min',
'parallax': '/bower_components/parallax.js/parallax.min',
'slick': '/bower_components/slick-carousel/slick/slick.min',
'domReady': '/bower_components/requirejs/domReady',
//Controllers
'HomeController': 'Components/Home/home.controller',
},
shim: {
angular: {
exports: "angular",
},
'angular-route': ['angular'],
'angularAMD': ['angular'],
'angular-slick': ['angular', 'slick'],
'angular-sanitize': ['angular'],
'materialize': ['jquery', 'jquery-hammer', 'hammerjs'],
'parallax': ['jquery'],
},
baseUrl: "src",
deps: ['app']
});
});
app.js
define(['angularAMD', 'angular-route', 'angular-sanitize', 'angular-slick'], function(angularAMD) {
var app = angular.module("app", ['ngRoute', 'ngSanitize', 'slick']);
app.config(function($routeProvider, $locationProvider) {
$routeProvider.when("/", angularAMD.route({
templateUrl: 'views/Home/home.html',
controller: 'HomeController',
controllerAs: 'vm'
}));
$locationProvider.html5Mode(true);
});
return angularAMD.bootstrap(app);
});
I've tried many differents ways, but none of them seems to work, what am i doing wrong?..
Note: it only happens sometimes, when the page loads..
Well since my last question was deleted, I was able to fix this issue. First: This maybe my neurosis, but add baseUrl before your paths array.
Second: (In your app.js), instead of
app.config(function($routeProvider, $locationProvider) {
$routeProvider.when("/", angularAMD.route({
templateUrl: 'views/Home/home.html',
controller: 'HomeController',
controllerAs: 'vm'
}));
$locationProvider.html5Mode(true);
});
return angularAMD.bootstrap(app);
Do this:
var app = angular.module("app", ['ngRoute', 'ngSanitize', 'slick']);
app.init = function () {
angular.bootstrap(document, ['app']);
};
return app;
This will load it to the DOM. If you have several controllers do so like this.
require.config({
baseUrl: "src",
paths: {
//Angular
'angular': '/bower_components/angular/angular',
'angular-route': '/bower_components/angular-route/angular-route.min',
'angularAMD': '/bower_components/angularAMD/angularAMD.min',
'angular-slick': '/bower_components/angular-slick/dist/slick.min',
'angular-sanitize': '/bower_components/angular-sanitize/angular-sanitize',
//Plugins
'jquery': '/bower_components/jquery/dist/jquery',
'materialize': '/bower_components/Materialize/dist/js/materialize.min',
'jquery-hammer': '/bower_components/Materialize/js/jquery.hammer',
'hammerjs': '/bower_components/Materialize/js/hammer.min',
'parallax': '/bower_components/parallax.js/parallax.min',
'slick': '/bower_components/slick-carousel/slick/slick.min',
'domReady': '/bower_components/requirejs/domReady',
},
shim: {
jquery: { exports: '$' },
angular: {
exports: "angular",
},
'angular-route': {
deps: ['angular'],
exports: 'angular'
},
'angularAMD': {
deps: ['angular'],
exports: 'angular'
},
'angular-slick': ['angular', 'slick'],
'angular-sanitize': {
deps: ['angular'],
exports: 'angular'
},
'materialize': ['jquery', 'jquery-hammer', 'hammerjs'],
'parallax': ['jquery'],
},
deps: ['app']
});
require(['app', 'other_controller', 'other_controller'], function(app) {
app.init();
});
Lastly make sure, you do not have ng-app in your html.
Related
I've got an HTML template (from themeforest) which has lots of jQuery plugins and a main.js where all of them are instantiated and configured for the template. I'm creating an AngularJS application based on that template, and i'm using RequireJS to load my scripts. In the index.html of the template, I load my require-config.js file. 80% of the times, the app loads just fine, but the other 20%, an error appears like "jQuery is not a function" or "$(...).mmenu is not a function". Here are my files. Can someone figure out what am I doing wrong?
<script type="text/javascript" src="js/jquery-lib.js"></script><!-- Jquery Library -->
<script type="text/javascript" src="js/jquery-migrate-1.3.0.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src='js/mapbox.js'></script>
<script type="text/javascript" src='js/leaflet.markercluster.js'></script>
<script type="text/javascript" src="js/build.min.js"></script>
<script type="text/javascript" src="lib/chosen/chosen.jquery.js" ></script>
<script type="text/javascript" src="js/jquery-ui.js"></script>
<script type="text/javascript" src="lib/slick/slick.min.js"></script>
<script type="text/javascript" src="lib/jquerym.menu/js/jquery.mmenu.min.all.js"></script>
<script type="text/javascript" src="lib/Magnific-Popup-master/jquery.magnific-popup.min.js"></script>
<script type="text/javascript" src="lib/jQuery.filer-master/js/jquery.filer.min.js"></script>
<script type="text/javascript" src="js/bootstrap-rating.js"></script>
<script type="text/javascript" src="lib/popup/js/classie.js"></script> <!-- Popup -->
<script type="text/javascript" src="lib/popup/js/modalEffects.js"></script> <!-- Popup -->
<script type="text/javascript" src="js/main.js"></script>
Where the last one is the main.js, where everything is initialized. So now, in my index.html I have this:
<script data-main="require-config" src="bower_components/requirejs/require.js"></script>
My require-confing.js looks like this
require.config({
paths: {
jquery: 'js/jquery-lib',
jquerymigrate: 'js/jquery-migrate-1.3.0.min',
rating: 'js/bootstrap-rating',
build: 'js/build.min',
mapbox: 'js/mapbox',
leaflet: 'js/leaflet.markercluster',
chosen: 'lib/chosen/chosen.jquery',
jqueryui: 'js/jquery-ui',
slick: 'lib/slick/slick.min',
jquerymenu: 'lib/jquerym.menu/js/jquery.mmenu.min.all',
magnific: 'lib/Magnific-Popup-master/jquery.magnific-popup.min',
fileLoader: 'lib/jQuery.filer-master/js/jquery.filer.min',
main: 'js/main',
angular: 'bower_components/angular/angular',
angularRoute: 'bower_components/angular-route/angular-route',
angularMocks: 'bower_components/angular-mocks/angular-mocks',
angularTranslate: 'bower_components/angular-translate/angular-translate',
angularTranslateLoadProvider: 'bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files',
text: 'bower_components/requirejs-text/text'
},
shim: {
'jquery': {
'exports': 'jquery'
},
'jquerymigrate': {
deps: ['jquery']
},
'build': {
deps: ['jquery']
},
'mapbox': {
deps: ['jquery']
},
'leaflet': {
deps: ['jquery', 'jquerymigrate']
},
'chosen': {
deps: ['jquery']
},
'jqueryui': {
deps: ['jquery']
},
'slick': {
deps: ['jquery', 'jqueryui']
},
'fileLoader': {
deps: ['jquery']
},
'js/bootstrap-rating': {
deps: ['jquery'],
'exports': 'rating'
},
'jquerymenu': {
deps: ['jquery'],
'exports': 'jquerymenu'
},
'magnific': {
deps: ['jquery']
},
'main': {
deps: ['jquery', 'jqueryui', 'build', 'mapbox', 'chosen', 'fileLoader', 'rating', 'jquerymenu', 'slick', 'magnific']
},
'angular': { 'exports': 'angular' },
'angularRoute': ['angular'],
'angularTranslate': ['angular'],
'angularTranslateLoadProvider': ['angularTranslate'],
'angularMocks': {
deps: ['angular'],
'exports': 'angular.mock'
}
}
And finally my app.js like this
define([
'angular',
'angularRoute',
'angularTranslate',
'angularTranslateLoadProvider',
'jquery',
'build',
'mapbox',
'leaflet',
'chosen',
'jqueryui',
'rating',
'slick',
'jquerymenu',
'fileLoader',
'main',
'view1/view1',
'view2/view2'
], function (angular, angularRoute, view1, view2, angularTranslate, angularTranslateLoadProvider) {
// Declare app level module which depends on views, and components
return angular.module('myApp', [
'ngRoute',
'pascalprecht.translate',
'myApp.view1',
'myApp.view2'
]).config(['$routeProvider', '$translateProvider', function ($routeProvider, $translateProvider) {
$routeProvider.when('/menu', {
resolve: {
"prevent": function () {
window.location.href = window.lastPath;
}
}
}).otherwise({ redirectTo: '/view1' });
$translateProvider.useStaticFilesLoader({
prefix: 'translations/',
suffix: '.json'
});
$translateProvider.preferredLanguage('es');
}]);
});
Here is the problem according to me
Your order in define should match the arguments in the function.
For example,
define(['module1', 'module2',......, 'moduleK'], function(module1, module2,...., moduleK){
});
The order of arguments in your callback should match the order in which you are requireing the modules as dependencies in your define
Hence, your code should look something like this;
define([
'angular',
'angularRoute',
'angularTranslate',
'angularTranslateLoadProvider',
'jquery',
'build',
'mapbox',
'leaflet',
'chosen',
'jqueryui',
'rating',
'slick',
'jquerymenu',
'fileLoader',
'main',
'view1/view1',
'view2/view2'
], function (angular, angularRoute, angularTranslate, angularTranslateLoadProvider, $, build, mapbox, leaflet, chosen, jqueryui, rating, slick, jquerymenu, fileloader, main, view1, view2) {
.....
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 having difficulties setting up Skrollr using AngularJS & RequirejS.
Some articles suggested to set up Skrollr as a directive and that is the approach that I have been following. Unfortunately, Skrollr is not able to initialize. Specifically, when I try to call the skrollr.init() from the directive I get an error saying that skrollr is not defined.
Below is my code:
directives.js
define(['directivesFactory', 'skrollr'], function(directivesFactory){
directivesFactory.directive('skrollr', [function(){
var directiveDefinitionObject = {
link: function() {
skrollr.init();
}
};
return directiveDefinitionObject;
}]);
});
main.js
(function() {
'use strict';
require.config({
baseUrl: 'js',
paths: {
'angular': 'libs/angular-1.3.9',
'angularRoute': 'libs/angular-route-1.3.9',
'bootstrap': 'libs/modernizr-2.6.2-respond-1.1.0.min',
'jquery': 'libs/jquery-1.11.0.min',
'bootstrapJS': 'libs/bootstrap',
'jqueryElastislide': 'libs/jquery.elastislide',
'jqueryPpCustom' : 'libs/jquerypp.custom',
'modernizrCustom' : 'libs/modernizr.custom.17475',
'skrollr' : 'libs/skrollr.min'
},
shim: {
'angular': {
exports: 'angular'
},
'angularRoute': {
deps: ['angular']
},
'jquery': {
exports: '$'
},
'bootstrapJS': {
deps: ['jquery']
},
'jqueryElastislide':{
deps: ['jquery']
},
'jqueryPpCustom':{
deps: ['jquery']
},
'skrollr': {
exports: 'skrollr'
}
}
});
define('controllersFactory', ['angular'], function(angular) {
return angular.module('app.controllers', []);
});
define('servicesFactory', ['angular'], function(angular) {
return angular.module('app.services', []);
});
define('directivesFactory', ['angular'], function(angular) {
return angular.module('app.directives', []);
});
define('app', [
'angular',
'angularRoute',
'servicesFactory',
'controllersFactory',
'directivesFactory',
],
function(angular) {
return angular.module('app', ['app.services', 'app.controllers', 'app.directives', 'ngRoute']);
}
);
require(['app',
'jquery',
'skrollr',
'bootstrap',
'bootstrapJS',
'jqueryElastislide',
'jqueryPpCustom',
'modernizrCustom'],
function(app,
jquery,
skrollr,
bootstrap,
bootstrapJS,
jqueryElastislide,
jqueryPpCustom,
modernizrCustom) {
require([
'controllers/mainController'
],
function() {
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {templateUrl: 'templates/main.html', controller: "MainController"}).
otherwise({redirectTo: '/'});
}]);
angular.bootstrap(document, ['app']);
}
);
});
})();
From web inspector, I see that skrollr.min.js is loaded before the directives.js file so I believe the directives should be able to call the functions within skrollr.
Any suggestions would be greatly appreciated - thanks!
define(['directivesFactory', 'skrollr'], function(directivesFactory){
directivesFactory.directive('skrollr', [function(){
var directiveDefinitionObject = {
link: function() {
skrollr.init();
}
};
return directiveDefinitionObject;
}]);
});
You don't seem to have required skrollr here, you need to add the require.
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 am trying to load JQuery-Ui with a shim, but JQueryUi keeps timing out when I try to load it even when I know the path is correct.
require.config({
paths: {
jQuery: 'libs/jquery-wrapper',
jQueryUi: 'libs/jquery-ui-min',
jQuerySelectmenu: 'libs/jquery.ui.selectmenu',
Underscore: 'libs/underscore-wrapper',
Backbone: 'libs/backbone-wrapper',
},
shim: {'Backbone': {
//These script dependencies should be loaded before loading
//backbone.js
deps: ['Underscore', 'jQuery'],
//Once loaded, use the global 'Backbone' as the
//module value.
exports: 'Backbone'
},
'jQueryUi': {
deps: ['jQuery'],
},
'jQuerySelectmenu': {
deps: ['jQuery', 'jQueryUi']
}
}
});
require([
'jQuery',
'Underscore',
'Backbone',
'jQueryUi',
'jQuerySelectmenu'
],
function(App) {
require(['order!src/app']
, function (App) {
App.initialize();
});
});
I think what damee is offering stands for older version of requireJs. Just folllow this tutorial as I did: Load jQuery UI with requireJS
Try to use this project https://github.com/jrburke/jqueryui-amd to translate your jqueryui to modularized version. Then you can simply use it:
define(['jquery', 'jqueryui/tabs'], function($){
$('#tabs').tabs();
});
With requirejs config:
requirejs.config({
paths: {
'jqueryui': '/javascript-cdn/jqueryui/' //output form jqueryui-amd
},
shim: {
'jquery': {
deps: [],
init: function(){
return $;
}
},
'jqueryui': {
deps: ['jquery']
}
}
});
I hope this helps.