I'm having a navigation bar on my site, and it's being built in some chain:
// in Init method
nav
.hideContainer()
.fetchData()
.buildHTML()
.eventify()
.showContainer();
It's OK, and works fine for me. But in fetchData
method I use local data to load ( inline json). But now, I need to get remote data (from an ajax calling). Can I make it without changing Init
method?
I had an attempt to do this with an synchronous ajax call:
// in fetchData() method
var data;
$.ajax ({
async: false,
url : '/some/url/',
success : function(res) {
data = res;
}
});
return data;
But I know, that it's slow - it's blocking the browser while it's loading.
I know, that I can modify my Init
method, like in a such way:
nav
.hideContainer()
.fetchData(function(){
nav.buildHTML().eventify().showContainer()
});
But, I'd like not to modify Init
method, can I do this?
P.S. I think I should go in direction of Deffered
object. Am I right?
You cannot have $.ajax
working asynchronously and at the same time expect .fetchData()
to return with your data.
You are right that setting async: false
is bad and changing the init()
is a better alternative even when you lose elegant chaining.
You can change your code like this:
function fetchData() {
// ...
return $.ajax ({
url : '/some/url/',
success : function(res) {
data = res;
}
});
}
function init() {
// ...
nav
.hideContainer()
.fetchData()
.done(function() {
nav
.buildHTML()
.eventify()
.showContainer(); });
You don't have to introduce callbacks into fetchData()
function, because you can return deferred object returned by ajax()
and then call done()
on it - see documentation.