I'm trying to put together backbone application using the marionette plugin, and am having some trouble getting initializers to work the way I expected them to. I have the following code:
var MyApp = new Backbone.Marionette.Application();
MyApp.addRegions({
region1 : '#div1',
region2 : '#div2'
});
MyApp.Resources = { };
MyApp.bind('initialize:before', function (options) {
// display a modal dialog for app initialization
options.initMessageId = noty({
text : 'Initializing MyApp (this should only take a second or two)',
layout : 'center',
speed : 1,
timeout : false,
modal : true,
closeOnSelfClick : false
});
});
MyApp.addInitializer(function (options) {
$.ajax({
url: options.apiUrl + '/my-app-api-module',
type: 'GET',
contentType: 'application/json; charset=utf-8',
success: function (results) {
MyApp.Resources.urls = results;
console.log(MyApp.Resources.urls); // <- THIS returns an object
}
});
});
MyApp.bind('initialize:after', function (options) {
// initialization is done...close the modal dialog
if (options.initMessageId) {
$.noty.close(options.initMessageId);
}
if (Backbone.history) {
Backbone.history.start();
}
console.log(MyApp.Resources.urls); // <- THIS returns 'undefined' BEFORE the console.log in the initializer above
});
Note in the code above that I have two console.log
calls, one in the initializer, and one in the initialize:after
handler. Both log the same object property. As you can see, what I'm experiencing is that the console.log
call in the initialize:after
handler is getting called before the one in the success
handler of the initializer. I realize that this is because the initializer has an async call in it...what I need to know is, how can I make sure that all of the async code in my initializer(s) is complete before doing anything else in the application? Is there a good pattern for this? I've not found anything in the docs indicating how to handle this correctly.
Thanks.
how can I make sure that all of the async code in my initializer(s) is complete before doing anything else in the application?
Don't use the initialize:after
event. Instead, trigger your own event from the success
call, and then bind your app start up code from that one.
MyApp.addInitializer(function (options) {
$.ajax({
url: options.apiUrl + '/my-app-api-module',
type: 'GET',
contentType: 'application/json; charset=utf-8',
success: function (results) {
MyApp.Resources.urls = results;
// trigger custom event here
MyApp.vent.trigger("some:event:to:say:it:is:done")
}
});
});
// bind to your event here, instead of initialize:after
MyApp.vent.bind('some:event:to:say:it:is:done', function (options) {
// initialization is done...close the modal dialog
if (options.initMessageId) {
$.noty.close(options.initMessageId);
}
if (Backbone.history) {
Backbone.history.start();
}
console.log(MyApp.Resources.urls);
});
This way you are triggering an event after your async stuff has finished, meaning the code in the handler will not run until after the initial async call has returned and things are set up.
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