I'm playing around with returning promises from an AJAX method and seeing how I can use them to make my code more easier to read/functional. My current scenario is to have a function getBookIds
which issues an AJAX call to a database to return the title of a book based on its ID. There are five books in the table and an anchor tag whose text property corresponds to each book. I want some other fancy AJAX method to fire once all anchor tags have been clicked on. Here's what I've got so far:
HTML
<a href="#">1</a>
<a href="#">3</a>
<a href="#">4</a>
<a href="#">5</a>
<a href="#">7</a>
JS
//hacky globals
var bookArray = [];
bookArray.length = $('a').length;
//ajax function
function getBookIds(data) {
return $.ajax({
type: "POST",
url: "Service.asmx/GetBookById",
data: JSON.stringify({
'titleId': data
}),
dataType: "json",
contentType: "application/json"
});
}
//click handler
$('a').on('click', function () {
var index = $('a').index($(this));
var titleId = $(this).text();
getBookIds(titleId).done(function (results) {
bookArray[index] = results.d;
var isEmpty = arrayChecker(bookArray);
fancyAjax(isEmpty);
});
});
//checks for undefined values in the array
function arrayChecker(array) {
var isEmpty = 0;
$.each(array, function (key, val) {
if (val === undefined) {
isEmpty++;
}
});
return (isEmpty > 0);
}
//bool es from arrayChecker if no undefined then go AJAX
function fancyAjax(bool) {
if (!bool) {
alert('alert message for fancy stuff');
}
}
This is a contrived example, but I'm struggling to see how I could incorporate these promises into my daily work. Is this just a bad example to leverage the power of promises/deferreds in the first place? It seems that instead of the success
callback on AJAX, not I've got all my logic rolled up inside done
. Any suggestions on tackling this better?
I'm playing around with returning promises from an AJAX method and seeing how I can use them to make my code more easier to read/functional. My current scenario is to have a function getBookIds
which issues an AJAX call to a database to return the title of a book based on its ID. There are five books in the table and an anchor tag whose text property corresponds to each book. I want some other fancy AJAX method to fire once all anchor tags have been clicked on. Here's what I've got so far:
HTML
<a href="#">1</a>
<a href="#">3</a>
<a href="#">4</a>
<a href="#">5</a>
<a href="#">7</a>
JS
//hacky globals
var bookArray = [];
bookArray.length = $('a').length;
//ajax function
function getBookIds(data) {
return $.ajax({
type: "POST",
url: "Service.asmx/GetBookById",
data: JSON.stringify({
'titleId': data
}),
dataType: "json",
contentType: "application/json"
});
}
//click handler
$('a').on('click', function () {
var index = $('a').index($(this));
var titleId = $(this).text();
getBookIds(titleId).done(function (results) {
bookArray[index] = results.d;
var isEmpty = arrayChecker(bookArray);
fancyAjax(isEmpty);
});
});
//checks for undefined values in the array
function arrayChecker(array) {
var isEmpty = 0;
$.each(array, function (key, val) {
if (val === undefined) {
isEmpty++;
}
});
return (isEmpty > 0);
}
//bool es from arrayChecker if no undefined then go AJAX
function fancyAjax(bool) {
if (!bool) {
alert('alert message for fancy stuff');
}
}
This is a contrived example, but I'm struggling to see how I could incorporate these promises into my daily work. Is this just a bad example to leverage the power of promises/deferreds in the first place? It seems that instead of the success
callback on AJAX, not I've got all my logic rolled up inside done
. Any suggestions on tackling this better?
- 1 Great question but it belongs in: codereview.stackexchange. – John Strickler Commented Jan 13, 2014 at 21:30
- 1 @JohnStrickler not every question with code belongs in codereview. He is asking about a concept and the code is an example not production code. This question is on topic here and it's not even a bad one :) – Benjamin Gruenbaum Commented Jan 13, 2014 at 21:31
- 1 @JohnStrickler I post there as well, I'm happy to have it migrated to where it's most appropriate. – wootscootinboogie Commented Jan 13, 2014 at 21:31
1 Answer
Reset to default 6I want some other fancy AJAX method to fire once all anchor tags have been clicked on.
That sounds like you want to get a promise for each click, which you can then bine into a promise for all clicks. The point is not to use a global booksArray
, but an array of promises.
function getBookIds(data) { … } //ajax function as before
var promises = $('a').map(function() {
var $this = $(this),
click = $.Deferred();
$this.one('click', function() { // click handler
click.resolve($this.text());
});
return click.then(getBookIds); // returns a promise for the ajax result
// after the link has been clicked
}).toArray();
$.when.apply($, promises).then(function fancyAjax() {
alert('alert message for fancy stuff');
});
(Demo)