Ajax Jquery Function response - javascript

I am learning to use jQuery Ajax. What does function(response) mean and what is the meaning of response == 1 and response == 2?
jQuery.post(ajaxurl, data, function(response) {
if (response == 1) {
$saveAlert.addClass('is-success').delay(900).fadeOut(700);
setTimeout(function() {
$tieBody.removeClass('has-overlay');
}, 1200);
} else if (response == 2) {
location.reload();
} else {
$saveAlert.addClass('is-failed').delay(900).fadeOut(700);
setTimeout(function() {
$tieBody.removeClass('has-overlay');
}, 1200);
}
});

I'll explain the basics:
jQuery.post = You want to post some data to your endpoint
ajaxurl = your endpoint address. Typically a API
data = the data you want to send to your endpoint along with the request.
function(response) is where you handle the response from the endpoint.
So lets go through the code. First you call post to your endpoint / API with the data you want to post. Then you provide a callback (in your case a function) to handle the response the endpoint / API provides you.
In your case it looks like if the endpoint responds with 1, you have successfully posted your data. If the endpoint responds with 2, you have posted data and want to reload the site. If the endpoint does NOT respond with either 1 or 2, it failed to post.
To help you understand the basics of jQuery post:
A well-written API / endpoint should respond with the correct HTTP status codes and status messages and it should be fairly easy to notice when data was posted correctly and when an error occurred.
I don't think your endpoint responds any good. response == 1 or response == 2is not by any means clear and easy to understand.
A better way of handling success and errors is to use the done and fail handlers of jquery post (more on this below).
$.post( "test.php" );
This will completely ignore the response from calling the endpoint. I.e. you don't want to handle either success or error. PLEASE DO NOT USE THIS. You should handle success and error!
$.post( "test.php", function( data ) {
//Do something now
});
This will do whatever you provide in the function when the endpoint has sent its response.
$.post( "example.php", function() {
//You successfully reached the endpoint
console.log( "success" );
})
.done(function() {
//Handle success here!
})
.fail(function() {
//Handle error here
})
This is probably the preferred way of handling both success and errors. It's pretty clear that if you reach the fail, it has failed. Both easy to read the code and easy to understand jquery post!
The examples above is copied from the jquery documentation.
Note that the previous handlers for done and fail was success and error, but success and error is deprecated and removed in jQuery 3.0!
So if you have jQuery version < 3.0 you need to find out if you need to use the new or old syntax, or if you need to update jQuery maybe?
Hope this explains enough to make you understand the basics, and to help you get further. I highly suggest you read the jQuery.post documentation here. I think you should also read the w3schools documentation here.

Related

Can't return any data from jQuery Post

I've been searching for an answer on this one, but none of the answers I found help resolving this issue:
HTTP Post via jQuery is not returning any data.
Here is the javascript code:
$.post(
<ENDPOINT_URL>,
<XYZ DATA SENT>,
function(data){
//THIS IS THE PROBLEM HERE
},
"json")
.fail(function(jqXHR, textStatus, errorThrown){
alert(textStatus);
});
This calls my endpoint API Url fine, which returns code 200 and a JSON response body:
{message: "XYZ"}
So here is what I've done so far:
Because of the asynchronous behavior, I created a function to receive and process the data input. Nothing happens still.
Added the .fail to process failures. According to an article my JSON returned may be incorrectly formatted and placing that .fail to process a failure may let me know what's going on... Is there a way to get the actual error message details?
Validated my JSON. Is it incorrectly formatted or something I'm not realizing?
Replaced the entire code with $ajax instead. Still, getting the same error.
I want to be able to receive that response and process the message "XYZ".
Thank you everyone for your help, much appreciated.
Tutorials/Articles I've followed:
https://api.jquery.com/jquery.post/
How do I return the response from an asynchronous call?
why cant I return data from $.post (jquery)
All, thank you very much for all of the feedback - the issue is now resolved. #Austin French, after reviewing the full method on both the server side and client side javascript, I realized the issue was related to headers.
My apologies for not expanding further on my question and providing further details: I am using Amazon AWS API Gateway to process a backend Lambda function, the client calls out to the function, the function does the job and returns the JSON:
{"message":"xyz"}
I wasn't received this message on the client side using jQuery $.post. The problem came down to how AWS API Gateway processes the request and returns the response.
I needed to include the following headers as part of my Lambda's function response:
"Access-Control-Allow-Origin" : "*"
Here is the full code for the server side response:
//Response
let responseCode = 200;
var responseBody = {
message: responseMessage
};
var response = {
statusCode: responseCode,
headers: {
"Access-Control-Allow-Origin" : "*"
},
body: JSON.stringify(responseBody)
};
Now on the client side, my original function(data){...} receives the response and is able to process it correctly, no errors are being triggered. Client side response handler:
function(data){
alert(JSON.stringify(data));
}
Thanks again everyone for your help!
Try following:
$.post(
ENDPOINT_URL,
myData,
function(data) {
var response = jQuery.parseJSON(data);
console.log(response);
}
);
This is the way I usually use it. It sends data as if sent in an html form and receives json response.
var value1, value2;
$.ajax({
type: "POST",
url: url,
data: {"property1" : value1, "property2" : value2},
success: function(result, status, xhr){
<here you can process the json you get as response in result}
},
error: function(xhr, status, theError){
<here process if ajax fails>
},
dataType: "json"
});
A couple things that won't fit in a comment:
I prefer this format for AJAX:
var myUrl = $(selector).val();
$.post( myUrl, { name: "John", time: "2pm" })
.fail(function (data) { /* code for failure */ }),
.done(function( data ) {
alert( "Data Loaded: " + data );
});
To see what the server is returning however, an easy thing to do is use Chrome's debugger:
Go to the network tab, choose the calling method and then on the right sub pane choose response. You should be able to see not only the response code, but the full contents returned.
A couple additional notes:
the .Done will call the function once the AJAX completes.
Depending on Jquery version you might not have not have a .done but rather .success and vice versa.

Ajax file upload returns status code 0 ready state 0 (only sometimes)

I have looked at the following thread
jQuery Ajax - Status Code 0?
However I could not find a definitive answer and I am having serious trouble trying to find the source of my issue so I am posting here in the hopes that someone can point me in the right direction.
In my code I am performing an Angular HTTP post which just sends basic JSON data, then within the on success callback I am using AJAX to upload files to the same server. (I know I should not be using jQuery and Angular however I can't change this for the moment)
It looks something like this
var deferred = $q.defer()
// first post
$http.post(url,payload,{params: params, headers: headers)
.then(function(response) {
uploadFiles(response,deferred);
// I am also sending google analytics events here
}, function(error) {
// do error stuff
}
return deferred.promise;
// upload files function
function uploadFiles(response,deferred){
$ajax({
type: 'POST',
processData: false,
contentType: false,
data: data // this new FormData() with files appended to it,
url: 'the-endpoint-for-the-upload',
dataType: 'json',
success: function(data) {
// do success stuff here
deferred.resolve(data);
},
error: function(jqXHR, textStatus, errorThrown) {
var message = {};
if (jqXHR.status === 0) {
message.jqXHRStatusIsZero = "true";
}
if (jqXHR.readyState === 0) {
message.jqXHRReadyStateIsZero = "true";
}
if (jqXHR.status === '') {
message.jqXHRStatusIsEmptyString = "true";
}
if (jqXHR.status) {
message.jqXHRStatus = jqXHR.status;
}
if (jqXHR.readyState) {
message.jqXHRReadyState = jqXHR.readyState;
}
if (jqXHR.responseText) {
message.jqXHR = jqXHR.responseText;
}
if (textStatus) {
message.textStatus = textStatus;
}
if (errorThrown) {
message.errorThrown = errorThrown;
}
message.error = 'HTTP file upload failed';
logError(message);
deferred.resolve(message);
}
}
})
}
Not my exact code but almost the exact same.
The issue is that is works almost all of the time, but maybe three or four in every few hundred will fail. By fail I mean the error handler function is called on the file upload function and the files are not uploaded.
I get jqXHRStatus 0 and jqXHRReadyState 0 when this occurs.
The only way I am able to replicate the issue is by hitting the refresh on the browser when the request is being processed, however users have advised they are not doing this (although have to 100% confirm this)
Is there perhaps a serious flaw in my code which I am not seeing? Maybe passing deferred variable around isn't good practice? Or another way the ajax request is being cancelled that I am not considering? Could sending google analytics events at the same time be interfering?
Any advice would be great and please let me know if you would like more information on the issue.
This means, the request has been canceled.
There could be many different reasons for that, but be aware: this could be also due to a browser bug or issue - so i believe (IMHO) there is no way to prevent this kind of issues.
Think for example, you get a 503 (Service Unavailable) response. What you would do in such a case? This is also a sporadic and not predictable issue. Just live with that, and try to repost your data.
Without reinventing the wheel, I suggest you to implement:
Retrying ajax calls using the deferred api
My guess is that your code is executing before it actually gets back from the call. I.e. the call goes back and nothing was returned and it gives a 0 error. This would make sense as the error is variable. Most of the time it would return fine because the backend executed fast enough but sometimes it wouldn't because it took especially long or something else happened etc. Javascript doesn't ever REALLY stop execution. It says it does but especially passing between angular and jquery with multiple ajax requests it wouldn't be surprising if it was executing the second ajax call before it actually completed your angular post. That's why a refresh would replicate the error because it's would clear your variables.
Some things you can do to test this:
On the backend make a timer that goes for a few seconds before it returns anything. This will probably make your code fail more consistently.
Set breakpoints and see when they are being hit and the values they contain in the javascript.
Good luck!

jQuery AJAX request to remote API blocked

I have been successfully accessing data from an external weather data service API for some time now using PHP cURL. Sometimes it takes a few seconds, sometimes up to 15 seconds for this web service to process my request. Therefore, I would like to perform this operation asynchronously.
I am trying jQuery AJAX to send this GET request now. However, it keeps throwing the following error:
"No Access-Control-Allow-Origin header is present on the requested resource".
I'm aware of the "same origin policy" restrictions, and have been researching it extensively here on stackoverflow and the jQuery docs. The docs say that JSONP requests are not subject to this restriction. When I try to designate JSONP as the dataType, I get an "unexpected token" syntax error.
I have the user entering in their zip code into a form text box, then click the button to submit. This sends the GET request to the web service. I'm very comfortable with PHP, but a newbie with jQuery and AJAX. I appreciate the help with this, and look forward to the day when I can help others as I've been helped here.
Here is the jQuery code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"> </script>
<script type="text/javascript">
$(document).ready(function () {
$('#btnGetETo').click(function () {
var resultElement = $('#resultDiv');
var requestData = $('#txtZip').val();
$.ajax({
url: 'http://et.water.ca.gov/api/data?appKey=B51CF64B-C37B-406A-83F1-1DBD8CE40EEF&targets=94805&startDate=2015-07-01&endDate=2015-07-01&dataItems=day-asce-eto,day-eto,day-precip&unitOfMeasure=E;prioritizeSCS=Y',
method: 'get',
data: { q: requestData },
dataType: 'json',
success: function (response) {
if (response.message != null) {
resultElement.html(response.message);
}
else {
resultElement.html('ETo: ' + response.DayAsceEto[0].value);
}
},
error: function (err) {
alert(err);
}
});
});
});
</script>
Unfortunately, it seems that the API in question does not support JSONP. In fact, they seem to have gone out of their way to make it difficult to query via JavaScript.
Here's how to test for JSONP (not foolproof, but most mainstream JSONP-enabled services will respond correctly). Take whatever URL you were planning to send, and add &callback=foo to the end of it. (If there are no other query string parameters of course, use ? instead of &.)
If the server supports JSONP, the response should look like:
foo({
...
});
If not, it'll look like:
{
...
}
As you can see, the only difference is that JSONP-enabled servers can wrap the JSON in a function of arbitrary name. Some servers will insert a little extra code for safety/convenience. For example, the following output was generated by the JSONplaceholder API using the URL http://jsonplaceholder.typicode.com/users/1?callback=foo:
/**/ typeof foo === 'function' && foo({
"id": 1,
"name": "Leanne Graham"
...
});
The upshot of all this is that it's the API provider's fault, not yours. If I were giving them feedback I'd make the following suggestions:
Handle cross-origin requests correctly.
Allow fallback to JSONP.

JSONP Syntax Error

I'm writing a jQuery interface to use a couple of OData services created in SAP. The services is working ok, and are also being used by some other applications.
I've already searched and I'm mostly come across people who are saying it's a cross domain issue. The first thing I tried was to plain and simply do a cross domain ajax call:
$.ajax({
url : 'http://saphostname:8000/sap/opu/odata/sap/entityset/?$format=json',
crossDomain : true,
xhrFields {
withCredentials : true,
}
// .. success, statusCodes, whatever ..
})
The responses that came from this call were 200, and if I viewed the content in the developer tools I saw my json message as I would expect it to be in there, but none of my callback functions were being triggered.
Upon searching more, somebody suggested using $.getJSON(). This didn't work either. The error that kept coming back was 401, so I assumed it was a cross domain issue.
The last thing I stumbled upon was JSONP. The response is coming back with an OK status code, and once again if I view the body content I see my json string as I would expect it. The only problem is my browser says there is a syntax error in the response text.
All of my search results have brought up issues regarding cross domain requests, and errors resulting there-in. Maybe it is the issue, but because I'm getting the results back that I would expect in the responses, I'd have to assume that connectivity is no problem.
tl;dr: ajax cross-domain requests are successful but don't trigger callback functions and jsonp gives me a syntax error. I'm not sure where to keep looking.
You are trying to do a JSONP request to a JSON service. The way that the response is handled for a JSONP request is that it is executed, but executing a JSON response only evaluates it and discards it.
The crossDomain property only causes the request to act like a cross domain request, i.e. using JSONP, regardless if it's actually to a different domain or not.
You should specify dataType: 'json' in the properties, to keep it from using JSONP.
Alternatively, if the service also supports JSONP, you could change $format=json in the URL to $format=jsonp, and specify dataType: 'jsonp' in the properties.
Edit:
Another thing that you can try is to use a proxy that turns a JSONP request to a JSON request. I have set up such a proxy that you can use to test if you can get the right response:
$.get(
"http://jsonp.guffa.com/Proxy.ashx?url=" + escapeURIComponent("saphostname:8000/sap/opu/odata/sap/entityset/?$format=json"),
function(data) {
console.log(data);
},
"jsonp"
);
I already had a problem like this before and what helped me to solve the problem was using callbacks like these:
// Assign handlers immediately after making the request,
// and remember the jqXHR object for this request
var jqxhr = $.ajax( "example.php" )
.done(function() {
alert( "success" );
})
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "complete" );
});
// Perform other work here ...
// Set another completion function for the request above
jqxhr.always(function() {
alert( "second complete" );
});
Now you can see which one is being triggered and debug the problem.

Force Backbone fetch to always use POST

I have a Collection that needs to POST some data to its url to get the data it needs. The answer to these two questions, Fetch a collection using a POST request? and Overriding fetch() method in backbone model, make it seem like I should be able to get it to work like this:
fetch: function( options ) {
this.constructor.__super__.fetch.apply(this, _.extend(options,{data: {whatever: 42}, type: 'POST'}));
}
, but Firebug still shows me a 404 error that is happening because a GET is being executed against the url in question (and the underlying Rails route only allows POST). Should this be working? If so, what else might I try? If not, what have I done wrong?
After reading the question again, here's a way to force the fetch to use POST per fetch call. (Thanks for the comments)
yourCollection.fetch({
data: $.param({id: 1234}),
type: 'POST',
success: function(d){
console.log('success');
}
});
Another approach is to override the AJAX implementation itself to use POST for all calls.
Backbone.ajax = function() {
var args = Array.prototype.slice.call(arguments, 0);
_.extend(args[0], { type: 'POST' });
return Backbone.$.ajax.apply(Backbone.$, args);
};

Categories