jQuery ajax requests repeats when error occurs - javascript

I've read through several posts related this this kind of issue, but I'm still not identifying the issue here.
When the following function is called and receives a 200 response, all is well; when it encounters 404 the ajax is repeated; adding a timeout only limits the time frame during which the repeat requests are made. There has to be a simple reason for this, but it is eluding me ...
function myFunction(ID) {
var url = 'http://example.org/' + ID;
var response;
$.ajax(url, {
success: function (responseText) {
if (responseText !== undefined) {
response = responseText;
}
},
error: function (xhr, ajaxOptions, errorMsg) {
if (xhr.status == 404) {
console.log('404: ' + errorMsg);
} else if (xhr.status == 401) {
console.log('401: ' + errorMsg);
}
}
});
return response;
}

You can use the below given approach to get the data for your error without repetition in AJAX.
$.ajax(url, {
success: function (responseText) {
if (responseText !== undefined) {
response = responseText;
}
},
error: function (xhr) {
//the status is in xhr.status;
//the message if any is in xhr.statusText;
}
});
UPDATE
You cannot return the response because you have an async request and response variable will be returned before the actual ajax requests gives a response. So I suggest You either use a callback function on success ore use a synchronous request.
So to get the response you can have a function like so:
function getResponse() {
return $.ajax({
type: "GET",
url: your_url,
async: false
}).responseText;
}
Or the callback approach is:
$.ajax(url, {
success: function (responseText) {
if (responseText !== undefined) {
theCallbackFunction(responseText);
}
},
error: function (xhr) {
//the status is in xhr.status;
//the message if any is in xhr.statusText;
}
});
function theCallbackFunction(data)
{
//do processing with the ajax response
}

Related

JQuery - Tried to connect server but ajax returning Code 0

I'm trying to check if same email exist in server db, but ajax is returning code 0 even my server is opened.
I checked it by using URL in browser.
if (input == email.find(".form_input").val()) {
emailChecking = true;
$.ajax({
url: "https://localhost:8888/check?target=" + input,
async: true,
type: "GET",
dataType: "text",
success: (data) => {
console.log(data);
if (emailChecking == true) {
emailChecking = false;
inputField(email, error);
}
},
error: (request, status, errorLine) => {
if (emailChecking == true) {
emailChecking = false;
error = "cannot check email - code " + request.status;
inputField(email, error);
}
}
});
}

Calling sync ready made async ajax javascript function

I want to call this function on button click after login and wait for result, to get token value. This function cannot be changed, it is async and supplied from other currently unavailable team.
I already tried something like this, but with no success. I get web service results, but I can't write appropriate sync call to wait to return token.
function getToken() {
param1 = "123456";
ajax_oauth(param1, function (success, response) {
success: return response.token;
});
}
function ajax_oauth(param1, callback) {
APP.debug("oauth login with param1 " + param1);
try {
APP.blockUI();
var DeviceID = APP.readRegistry(APP_CONFIG.REGISTRY.DeviceID);
//---------------------------------------------------------------
$.ajax(
auth_token_url,
{
method: "GET",
accept: 'application/json',
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: JSON.stringify({
'param1': param1,
'deviceId': DeviceID
}),
xhrFields: {
withCredentials: false
},
statusCode: {
201: function (response) {
APP_STATE.hasOauth = true;
APP.debug('got response 200 from oauth');
auth.login(response.token); //TODO read expiration from token
try {
var decoded = jwt_decode(response.token);
APP_STATE.uid = decoded.uid;
} catch (err) {
APP.error("unable to decode token " + JSON.stringify(err));
}
},
401: function () {
},
500: function () {
},
503: function () {
}
},
success: function (response) {
APP.unblockUI();
APP_STATE.restAvailable = true;
},
error: function (jqXHR, textStatus, errorThrown) {
APP.unblockUI();
APP_STATE.restAvailable = false;
APP.restError(auth_token_url, jqXHR, errorThrown, textStatus);
APP.callback(callback, false);
}
}
);
} catch (err) {
APP.error("unable to do oauth login, " + err);
}
};
After user clicks on login button, I want to call function ajax_oauth and to return token if params ok. If not, to return login error. Login can't be async, as far as I can see.
For whatever reason you can't tap into the original ajax response, you could intercept the request using $.ajaxPrefilter.
From your code it looks like auth_token_url has a global reference. You could use this to intercept the call by matching the outgoing request on the resource URL.
$.ajaxPrefilter('json', function(options, originalOptions, jqXHR) {
if (options.url === auth_token_url) {
jqXHR.done(function(response) {
try {
var decoded = jwt_decode(response.token);
console.log(decoded);
} catch (err) {
APP.error("unable to decode token " + JSON.stringify(err));
}
});
}
});
Note that this needs to be declared well before the request is made preferably after jQuery is loaded.

Show an error when email is not sent

I have the following example form below where beforeSend function shows a message that is sending and once it is sent an other function is called .done(function (data) showing a message that message has been sent. All I want to do is to use another function where the message is not sent, to display the message "error, message is not sent"
var form = $('#main-contact-form');
form.submit(function (event) {
$.ajax({
type: 'POST',
url: '../sendemail.php',
data: {
Name: name,
Subject: $form.find("input[name='subject']").val(),
Email: email,
message: $form.find("textarea[name=message]").val(),
},
beforeSend: function () {
// message is sending...
}
}) //end ajax
.done(function (data) {
// message sent!
});
});//end contact form
You can use fail api to handle errors as shown below.
Also, in the $.ajax({constObj}) you can have apis like success and error to handle the same.
Refer here for more info
//1.
$.ajax({
type: 'POST',
url: '../sendemail.php',
data: {
Name: name,
Subject: $form.find("input[name='subject']").val(),
Email: email,
message: $form.find("textarea[name=message]").val(),
},
beforeSend: function () {
// message is sending...
}
}) //end ajax
.done(function (data) {
// message sent!
})
.fail(function(){
//handle error here
});
//2.
constObj.success(function(data){
});
constObj.error(function(error){
});
Instead of .done use ajax options success and error. Throw error on server when sending email fails.
$.ajax({
success: function () {
// message sent!
},
error: function () {
// message sent failed!
}
});
On server side:
if ($this->sendMessage()) {
echo "ok";
} else {
throw new Exception('Email failed to send.', 500);
}
You can't tell if user actually receives email (I guess there is some complicated ways to figure it out).
You use done(), which is executed after a SUCCESSFUL ajax request (usually returns HTTP 200). If you read http://api.jquery.com/jquery.ajax/, there is fail(), which is executed after a FAILED ajax request.
It also depends the output of sendemail.php. If your PHP returns other than HTTP 200 when error, you can utilize fail() promise method, for example...
$.ajax({
beforeSend: function() {
$('msg').text('Sending email...');
}
}).done(function() {
$('#msg').text('Success!');
}).fail(function() {
$('#msg').text('Failed!');
});
But, if your PHP also returns HTTP 200 when error, you can do something like the following...
PHP:
$response = array(
'status' => null,
'error' => null
);
if ($mailer->send()) {
$response['status'] = true;
} else {
$response['status'] = false;
$response['error'] = 'Unable to send email';
}
jQuery:
$.ajax({
beforeSend: function() {
$('msg').text('Sending email...');
}
}).done(function(data) {
if (data.status === true) {
$('#msg').text('Success!');
} else {
$('#msg').text('Failed: ' + data.error);
}
});

How to replicate jQuery ajax method

The problem: I'm trying to replicate the jQuery ajax method since I'm using XMLHttpRequest more than once in a script. However, I do not think including jQuery as a dependency is necessary since I would only be using a maximum of 3 methods from the jQuery library. Therefor I need a good way of replicating the jQuery's ajax method and so far I've gotten this far but please see explanation of output below the code example:
function ajax(obj) {
/*
obj = {
type: 'GET',
url: 'my/url/',
success: function (response) {},
error: function (response) {},
isTrue: true
}
*/
var
response = null, // defaults to null
complete = function (resp) {
console.log(resp); // outputs the response
response = resp;
},
error = function (resp) {
response = resp;
},
request = new XMLHttpRequest();
request.open(obj.type || 'GET', obj.url, obj.isTrue || true);
request.onreadystatechange = function (e) {
if (request.readyState === 4) {
if (request.status >= 200 && request.status < 400) {
complete(request.responseText);
} else {
error(request.statusText);
}
}
}
request.send();
return {
done: function (callback) {
callback(response);
}
}
}
Then when I call the ajax function in another function:
var xhr = ajax({
url: 'js/routes.js',
}).done(function (resp) {
console.log(resp); // outputs 'null'
});
the response variable is null although the complete() function set the response variable to the value of the ajax .responseText.
Question: How can I return the value of .responseText from the request to the object the ajax function is returning so that I can do something with it in a callback function like I intend to do inside the .done() method of that object?
Thank you!
You have an error in your implementation. The 'done' function does not wait for response.
function ajax(obj) {
/*
obj = {
type: 'GET',
url: 'my/url/',
success: function (response) {},
error: function (response) {},
isTrue: true
}
*/
var _callback = null,
response = null, // defaults to null
complete = function (resp) {
if(_callback){
_callback(resp);
}
response = resp;
},
error = function (resp) {
if(_callback){
_callback(resp);
}
response = resp;
},
request = new XMLHttpRequest();
request.open(obj.type || 'GET', obj.url, obj.isTrue || true);
request.onreadystatechange = function (e) {
if (request.readyState === 4) {
if (request.status >= 200 && request.status < 400) {
complete(request.responseText);
} else {
error(request.statusText);
}
}
}
request.send();
return {
done: function (callback) {
if(response){
callback(response);
}else{
_callback = callback;
}
}
}
}
EDIT*
consider using a microlibrary instead of jQuery. Don't reinvent the wheel.
http://microjs.com/#ajax

401 Unauthorized Issue

I am using the jQuery.get() method
$.get('login.php', function(d, textStatus, jqXHR){
//alert(jqXHR.status)
var status = jqXHR.status;
if((status==200)||(status==202)){
window.location.href = 'dashboard.html';
}else if(status==401){
alert('Error in login details')
}else{
alert('Unknown Error')
}
});
It is working fine. When 200 & 202 , It will rediredt to dashboard page. But Other than 200 & 202, It pass the error in console but doesn't show alert.
You need to add in some event handlers for the fail state, which will handle 4xx and 5xx errors. The success state only handles HTTP codes which indicate a successful request. From http://api.jquery.com/jQuery.get
var jqxhr = $.get( "example.php", function(data, status) {
alert( "success - " + status );
})
.done(function(data, status) {
alert( "second success - " + status );
})
.fail(function(data, status) {
alert( "error - " + status );
})
.always(function(data, status) {
alert( "finished - " + status );
});
This is because the callback function you have defined is only called when a successful request completes. If the response is anything other than a 200, the request is considered to have errored. To do what you require, you could use the $.ajax() method:
$.ajax({
url: 'login.php',
success: function() {
window.location.assign('dashboard.html');
},
error: function(xhr) {
if (xhr.status == 401) {
alert('Error in login details')
} else {
alert('Unknown Error')
}
}
});

Categories

Resources