Angular + Requirejs - Loading in the wrong order
angularjs, asynchronous, javascript, jquery, requirejs
Solution
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.
Problem
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> ```