Reputation: 1390
I am currently moving my webpage over to a SPA (single page application) and in doing so I am now working with only one html page, which gets populated using JS (as a normal SPA should do). As such, that means (for convenience sake) I am cutting down my JS files to one (maybe a good idea, maybe a bad one - we'll see, but that's not the point). I have decided to make a "black box" AJAX request handler, so as to minimize code. This is where I ran into a problem I was not expecting. The code is (the example click
is for my login screen):
function ajaxCall(type, url, data, dataType) {
$.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
})
.done(function(xhr) {
return xhr;
})
.fail(function(xhr, status, errorThrown) {
console.log('AJAX call error: ' + errorThrown);
console.dir(xhr);
})
.always(function(xhr, status) {
console.log('AJAX call status: ' + status);
});
}
var res;
//this is inside $(document).ready - I just skipped some lines
$(document).on('click', '#submit', function(e) {
res = ajaxCall('POST', '/Login', { 'username': $('#username').val(), 'password': $('#password').val() }, 'json');
console.log('res =', res); // this is where the problem was discovered
});
(some of you are already groaning) Of course, when I tested this, what I got in my console is res = undefined
.
I have spent hours researching this problem, and have figured out why it happens. These are some of the pages I researched in trying to solve this: 1 2 3
To cut to the chase: The problem is that I am not using a Promise
. I got that. I can fix that. What I cannot seem to fix is using a plain JS Promise
with a jQuery AJAX request.
I have gotten this far:
function ajaxCall(type, url, data, dataType) {
return Promise.resolve($.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
}));
}
but I cannot figure out how to incorporate the other features/functions of a promise
, which are: .then() and .reject()
. As far as I understand, the above Promise will automatically resolve, but what if it needs to be rejected? Maybe I am still thinking with jQuery's .done(), .fail() and .always()
.
But for the life of me, despite all the Googling I do, I cannot find how to fully incorporate all the functions of a plain JS
Promise
with a jQuery AJAX request.
Thus, I am asking the stackoverflow community for insight into this problem.
Thank you.
Upvotes: 0
Views: 125
Reputation: 163
So Promise
isn't really your savior here. The issue you have is that you need to call the console.log('res =', res);
after the AJAX request is done using the .done()
and .fail()
methods.
function ajaxCall(type, url, data, dataType) {
return $.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
});
}
//this is inside $(document).ready - I just skipped some lines
$(document).on('click', '#submit', function(e) {
var res = ajaxCall('POST', '/Login', { 'username': $('#username').val(), 'password': $('#password').val() }, 'json');
res.done(function (data) {
console.log('res =', data);
});
});
If you really want to use a real Promise
, you can do something like
function ajaxCall(type, url, data, dataType) {
return new Promise(function (resolve, reject) {
$.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
}).done(function (data) {
resolve(data);
}).fail(function (jqXHR, textStatus, errorThrown) {
reject(errorThrown);
});
});
}
//this is inside $(document).ready - I just skipped some lines
$(document).on('click', '#submit', function(e) {
var res = ajaxCall('POST', '/Login', { 'username': $('#username').val(), 'password': $('#password').val() }, 'json');
res.then(function (data) {
console.log('res = ', data);
}).catch(function (err) {
console.error(err);
});
});
Upvotes: 2