I'm trying to have angular and jquery loaded with requirejs. The best I can do is that 50% of the time everything loads correctly, the other half I get the error No Module: mainApp
I'm assuming this is breaking half the time based on the speed on which requirejs is asynchronously loading the scripts.
When it works, I see the "Hello World" test (although I do see {{text}} flash before it is replaced, but I've been reading how to fix that here). The rest of the time I get the error and {{text}} just stays on the screen.
Github Repo
Tree:
index.html
- js
- libs
require.js
- modules
mainApp.js
main.js
main.js
require.config({
paths: {
'jQuery': '//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min',
'angular': '//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular',
},
shim: {
'angular' : {'exports' : 'angular'},
'jQuery': {'exports' : 'jQuery'}
}
});
require(['jQuery', 'angular', 'modules/mainApp'] , function ($, angular, mainApp) {
$(function () { // using jQuery because it will run this even if DOM load already happened
angular.bootstrap(document, ['mainApp']);
});
});
modules/mainApp.js
define(['angular'], function (angular) {
return angular.module('mainApp' , []).controller('MainCtrl', ['$scope', function ($scope) {
$scope.text = 'Hello World';
}]);
});
Relevant index.html
<head>
<script src="js/libs/require.js" data-main="js/main"></script>
</head>
<body>
<div ng-app="mainApp">
<div ng-controller="MainCtrl">
{{text}}
</div>
</div>
</body>
You can use domReady (UPDATED) to make sure that the DOM is fully loaded, i.e. all JS files are there, before bootstrapping your application.
requirejs.config({
paths: {
jquery: '/path/to/jquery',
angular: 'path/to/angular',
domReady: '/path/tp/domReady'
}, shim: {
angular: {
exports: 'angular'
},
}
});
define(['jquery', 'angular', 'modules/mainApp'],
function($, angular, 'mainApp') {
// tell angular to wait until the DOM is ready
// before bootstrapping the application
require(['domReady'], function() {
angular.bootstrap(document, ['mainApp']);
});
});
See the RequireJS official documentation for more information on this gotcha:
It is possible when using RequireJS to load scripts quickly enough that they complete before the DOM is ready. Any work that tries to interact with the DOM should wait for the DOM to be ready.
The trick is found on this blog post.
EDIT If you follow the blog post's advice, please use this domReady script instead of the one I previously posted: https://github.com/requirejs/domReady/blob/master/domReady.js.
Add Jquery as a dependency for Angular in the shim.
require.config({
paths: {
'jQuery': '//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min',
'angular': '//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular',
},
shim: {
'angular' : {'exports' : 'angular', deps: ['jQuery']},
'jQuery': {'exports' : 'jQuery'}
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With