parsing success callbacks from ajax call - javascript

I have a backbone object that I'm calling save on. How do I know what comes back in the ajax call. Looking at the code for the project I got put on, I see some people just have a generic
success: function (data) {
console.log(data);
Then other times, I see:
success: function (library, response) {
console.log(library);
console.log(response)
I'm confused on how you would know you would have I presume a library or response object, vs a general data. When I look at the second example, I am looking at the output of
console.log(response);
and I see response has three attributes:
Notifications
Response
ResponseStatus
Response itself looks like Object {Id="12345", href="the/href", Name="asdf"}
So it looks like a Javascript object to me, but then when I try to do
console.log(response.Name);
I always get undefined even though I can see the value.
So I'm trying to understand how the callback in an ajax calls. Like when you can use an actual library object, response object, vs a data object, and how I can go about parsing the results properly. Thanks in advance!

You should either
$.ajax({
dataType : 'json',
..
})
or
$.ajax({
..
success : function(data) {
var result = JSON.parse(data);
});
Then I think you will be good

Related

Ajax loop and response order

I am retrieving a series of data from a server (geoserver) using $.ajax.
The (simplified) request looks like this:
var dataList=[];
//var urllist= // a list of several URLs to request data from
$.each(urllist,function(i) {
$.ajax({
jsonpCallback: 'getJson',
type: 'GET',
url: urllist[i],
dataType: 'jsonp',
success: function(data) {
dataList[i]=data.value;
}
})
});
I need to write to the global variable dataList because I need to fire an event after all requests from urllist are finished. (I've got deferreds implemented like so).
The problem is that the finished list is always in a different order. I need the result to be in the same order as the requests.
It might be a problem of closure where the index i that is passed on to the ajax function and the allocation to dataList that is happening at a later point (when the each loop has moved on).
I tried taking care of that like this but the problem remains the same. Also $.each like in the code above should create a seperate closure for every iteration anyway.
I've managed to implement a recursive function but its synchronous.
edit: suggested duplicate does not deal with looped ajax requests
You can access all the results in $.when callback in the correct order
// map an array of promises
var deferreds = urllist.map(function(url){
// return the promise that `$.ajax` returns
return $.ajax({
url: url,
dataType: 'jsonp'
}).then(function(data){
return data.value;
})
});
$.when.apply($, deferreds).then(function(results){
// results will be array of each `data.value` in proper order
var datalist = results;
// now do whatever you were doing with original datalist
$.each(datalist....
}).fail(function(){
// Probably want to catch failure
}).always(function(){
// Or use always if you want to do the same thing
// whether the call succeeds or fails
});
The problem was not related to the deferreds but to the jsonp or the related jsonpcallback required for the request. Requesting the data as json solved the problem
credits to #charlietfl for the answer over at: Looped ajax request. Error handling and return order
For anyone looking this up: You most likely have to to enable Cross-Origin Resource Sharing on geoserver to be able to access the JSON directly

Error when storing JSON after an ajax request (jQuery)

I'm quite new to JavaScript/jQuery so please bear with. I have been trying to store the resulting JSON after an ajax request so I can use the login info from it later in my program. I get an error stating that "Data" is undefined. Here is the problematic code:
function LOGIN(){
$.ajax({
url: 'https://.......&JSONP=Data&.........',
success: function Success(){
var SessionData = Data();
(FunctionThatParsesJSON);
}
})
}
I have checked the URL manually and it works fine (including) being wrapped in the "Data" function. From what I have found online, this may be something to do with ajax been asynchronous. Can anyone suggest a way of storing the JSON so that I can use it later?
Try something like the following;
function LOGIN(){
$.ajax({
url: 'https://.......&JSONP=Data&.........',
success: function Success(data){
functionToProcessData(data)
})
}
When making your ajax call, you can handle the response given by assigning a parameter to the function. In the case above, I have passed the 'data' parameter to the success function allowing me to then use it in further functions (as demonstrated by 'functionToProcessData(data)'.
The response from ajax call is captured in success handler, in this case 'data'.
Check below code:
success: function(data){
var SessionData = data.VariableName;
// Here goes the remaining code.
}
})
Since people ask about explanation, thus putting few words:
When we do $.ajax, javascript does the async ajax call to the URL to fetch the data from server. We can provide callback function to the "success" property of the $.ajax. When your ajax request completed successfully, it will invoke registered success callback function. The first parameter to this function will be data came from server as response to your request.
success: function ( data ) {
console.log( data );
},
Hope this helps.
Internally everything uses promises. You can explore more on promises:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
Apparently you are using JSONP, so your code should look like this:
$.ajax({
url: 'https://.......&JSONP=Data&.........',
dataType:"jsonp",
success: function (data){
(no need to parse data);
}
});
Another option:
$.ajax({
url: 'https://.......&JSONP=Data&.........',
dataType:"jsonp"
})
.done(function (data){
(no need to parse data);
});
See the documentation and examples for more details.
success: function (data, textStatus, jqXHR){
these are the arguments which get passed to the success function. data would be the json returned.

JSON.parse works but jQuery.getJSON returns http error 403

When I use JSON.parse(jsonString), the JSON is parsed no problem at all.
var result = JSON.parse(jsonString);
But when I use jQuery.getJSON(jsonString) i received an http error 403.
var result = jQuery.getJSON(jsonString);
Any idea why one will work and the other will not? They are both reading a string.
Thanks!
They are both reading a string.
Oh no! Those two methods are so very much different. They have absolutely nothing in common. They are accomplishing 2 entirely different tasks.
The first simply parses a JSON string into a javascript object:
var result = JSON.parse('{"foo": "bar"}');
alert(result.foo);
will show bar. Also notice that the JSON.parse method is a built-in method in modern browsers. It's pure javascript and has strictly nothing to do with jQuery. Legacy browsers do not support it. For them you need to include the json2.js script to your page.
The second performs an AJAX call and expects as argument an url:
jQuery.getJSON('/someserversidescript', function(result) {
// callback to be executed when the AJAX request succeeds
});
As you can see here the argument is an url. Calling jQuery.getJSON('{"foo": "bar"}') makes strictly no sense. I guess that's the reason why your server responds with 403 error, since this is not valid url on your server. It expects that the server will return a JSON string as response. It's simply a shorthand for:
$.ajax({
url: '/someserversidescript',
type: 'GET',
dataType: 'json',
success: function(result) {
// callback to be executed when the AJAX request succeeds
}
});
getJSON() is an asynchronous call back to a server that returns a JSON object. JSON.parse() takes a string and returns a JSON object in memory. They are completely different.

Return String from Cross-domain AJAX Request

I'm looking for a way to return a single JSON/JSONP string from a cross-domain "AJAX" request. Rather than request the string and have JQuery return it as a generic object automatically, I want to get a hold of the string BEFORE that conversion happens. The goal here is to parse it myself so I can turn it straight into new objects of a certain type (e.g. a Person object).
So, just to make this clear, I don't want any string-to-generic-object conversion going on behind the scenes and this must work using a different domain.
Here's a non-working example of what I would like to do:
$.ajax({
type: 'GET',
url: 'http://www.someOtherDomain.com/GetPerson',
dataType: 'text',
success: parseToPerson
});
function parseToPerson( textToParse ) {
// I think I can do this part, I just want to get it working up to this point
}
I'm perfectly happy if JQuery isn't involved in the solution, as long as it works. I would prefer to use JQuery, though. From what I've read, the javascript techniques used to get JSONP data (dynamically creating a script element) would probably work, but I can't seem to get that to work for me. I control the domain that I am requesting data from and I can get the data if I change the dataType in the AJAX call to 'JSONP', so I know that is working.
If your data is being retrieved from another domain, you will need to use JSONP (there are other options, but JSONP is by far the easiest if you control the service). The jQuery call will look like this:
$.ajax({
// type: 'GET', --> this is the default, you don't need this line
url: 'http://www.someOtherDomain.com/GetPerson',
dataType: 'jsonp',
success: parseToPerson
});
The actual request that goes to your service will be http://www.someOtherDomain.com/GetPerson?callback=arbitrary_function_name. On the service side, you will need to return data like this:
arbitrary_function_name("the string (or JSON data) that I want to return");
So you'll need to inspect the querystring parameters, get the value of the callback parameter, and echo it out as if you're calling a Javascript function with that name (which you are), passing in the value you want to provide through the service. Your success function will then get called with the data your service provided.
If you're deserializing the returned data into a Javascript object, you might be better off returning JSON data than a string, so the data your service returns might look like this:
arbitrary_function_name({
"name":"Bob Person",
"age":27,
"etc":"More data"
});
That way you don't have to worry about parsing the string - it'll already be in a Javascript object that's easy to use to initialize your object.
Not sure how this will work in conjuction with jsonp, but maybe converters is what you're looking for?
$.ajax(url, {
dataType: "person",
converters: {
"text person": function(textValue) {
return parseToPerson(textValue);
}
}
});

Having problems with jQuery, ajax and jsonp

I am using jsonp and ajax to query a web-service written in java on another server. I am using the following jquery command:
$.ajax({
type: "GET",
url: wsUrl,
data: {},
dataType: "jsonp",
complete: sites_return,
crossDomain: true,
jsonpCallback: "sites_return"
});
function jsonp_callback(data) {
console.log(data);
}
function sites_return(data) {
console.log(data);
}
So my problem is that after the query finishes a function called jsonp_callback is called. Where I can clearly see the json formatted string:
{"listEntries":["ELEM1", "ELEM2", "ELEM3", etc...]}
But after the function sites_return is called when the complete event fires, I get the the following:
Object { readyState=4, status=200, statusText="parsererror"}
Also for reference the jsonp_callback function is called before the sites_return function. Also if i take the jsonp_callback function out of the code, I get a complaint it firebug that the function is not implemented.
My question three fold:
1) What am i doing wrong on the jquery side?
2) Why does the json get parsed correctly in jsonp_callback but not sites_return?
3) What can i do to fix these issues?
EDIT
Some new development. Per the comments here is some additional information.
The following is what comes out of the http response
jsonp_callback({"listEntries":["ELEM1", "ELEM2", "ELEM3"]})
I assume this is the reason jsonp_callback is being called. I guess my question now becomes, is there any way to control this (assuming i don't have access to the back end web-service).
Hope this helps~
var url = "http://maps.google.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false";
var address = "1600+Amphitheatre+Parkway";
var apiKey = "+Mountain+View,+CA";
$.getJSON("http://maps.google.com/maps/geo?q="+ address+"&key="+apiKey+"&sensor=false&output=json&callback=?",
function(data, textStatus){
console.log(data);
});
I believe that the first argument to the sites_return function would be the jqXHR Object. Instead of complete try using success.
But still this may not work as it seems that there is a parsing error (mentioned in the return value of sites_return function called from oncomplete). Therefore, you would first need to check your json string.
To Validate JSON, you can use http://jsonlint.com/
I think that the problem is that your server is not behaving the way jQuery expects it to. The JSONP "protocol" is not very stable, but generally what's supposed to happen is that the site should look for the "callback" parameter and use that as the function name when it builds the JSONP response. It looks as if your server always uses the function name "jsonp_callback".
It might work to tell jQuery that your callback is "jsonp_callback" directly:
$.ajax({
type: "GET",
url: wsUrl,
data: {},
dataType: "jsonp",
complete: sites_return,
crossDomain: true,
jsonpCallback: "jsonp_callback"
});
Not 100% sure however.
If you don't have the ability to change the JSONP function wrapper that the remote server returns, jQuery's $.ajax() may be overkill here. Ultimately, all you're doing is injecting a script reference to wsUrl, which makes a call to jsonp_callback with a JavaScript object literal as its input parameter.
You could just as easily do something like this and avoid the confusion around the callback naming/syntax:
$.getScript(wsUrl);
function jsonp_callback(response) {
// Access the array here via response.listEntries
}

Categories