Getting list back from ajax jsonp callback - javascript

I am making an ajax call via jquery with a jsonp callback function. The callback gets called and generates a list for me that I need to return to the original alling function and assign to a variable. However, it is not getting passed back. I know I am doing something wrong or misunderstanding how this flow works. Could somebody please point me in the correct direction? Here is the (abbreviated) code:
function() {
..build url...
var multiTargets = getMultiMetrics(url);
...do stuff with list...
}
getMultiMetrics = function(url) {
$.ajax({
url: url,
jsonp : true,
jsonpCallback: 'metricCallback',
cache: true,
dataType : 'jsonp',
async: false
});
};
metricCallback = function(data) {
var items = [];
for (var i = data.length - 1; i >= 0; i--) {
items.push(data[i].target);
};
return items;
};

Try not use quotes in
jsonpCallback: metricCallback,
This parameter must be function instead of a string

Related

How to access 'Object' portion of JSON using Jquery?

I used console.table(someData) to output the object shows in the attaches image.
I used the following code to get the data:
var someData = GetJson('someurlthatreturnsjson');
function GetJson(Url) {
return $.ajax({
url: Url,
xhrFields: {
withCredentials: true
},
dataType: "json"
});
}
I tried:
var x = someData.readyState; // 1 was returned as expected.
var y = someData.Object; // undefined.
...so...
var z = someData.Object.responseJSON; // also undefined?
So how would I access elements within the Object portion of this json? Am I missing something?
As you return the $.ajax() call from getJSON(), the someData variable will contain the Deferred object containing the reference to the AJAX call.
To retrieve the response from that call from the Deferred object you can use any of the methods outlined in the documentation I linked to. I would suggest using then() in this case, as the handler function you define will receive the response as the first argument to the function, like this:
var someData = GetJson('someurlthatreturnsjson').then(response => {
// do something with the response here...
console.dir(response);
});
function GetJson(Url) {
return $.ajax({
url: Url,
xhrFields: {
withCredentials: true
},
dataType: "json"
});
}

How to get synchronous result for jsonpCallback?

I want to call jsonpcallback function in while or for loop. But I am getting asynchronous results. How to achieve that in jsonpcallback. Kindly anyone help me out to fix this or provide any other solution.
window.onPublitoryOebPart = function(json) {
window.publitoryOebPartJson = json;
content = patchEditedContent(json);
saveOebPartToc(content);
}
i = 0;
while(i < $("#oeb_parts_count").val()) {
return unless $("#oeb-part-file-url-"+i).length > 0
fileUrl = $("#oeb-part-file-url-"+i).html();
$.ajax({
url: fileUrl,
crossDomain: true,
dataType: "script",
jsonpCallback: "onPublitoryOebPart"
})
i++;
}
JavaScript can't get a "synchronous" JSONP result. This is because JSONP involves creating a new script element; such a dynamically created script element can only load the resource asynchronously.
Just use the success callback for the JSONP request and handle the response asynchronously. Manually specifying the jsonpCallback is only required/useful if the service doesn't allow a dynamic function to be specified.
If using success callback in a loop, it's also important to read up on closures (and then read more).
For instance:
var i = 0; // Don't forget the "var"
while(i < $("#oeb_parts_count").val()) {
var elm = $("#oeb-part-file-url-"+i);
if (!elm.length) { return; } // Make sure to use valid syntax
var fileUrl = elm.html();
$.ajax({
url: fileUrl,
crossDomain: true,
dataType: "script",
success: function (i, fileUrl) {
// Return a closure, the i and fileUrl parameters above
// are different variables than the i in the loop outside.
return function (data) {
// Do callback stuff in here, you can use i, fileUrl, and data
// (See the links for why this works)
alert("i: " + i + " data: " + data);
};
})(i, fileUrl) // invocation "binds" the closure
});
i++;
}
It may be cleaner simply to create a closure via a named function, but it's all the same concept.
Synchronous XHR requests are also highly discouraged; XHR is not JSONP, even though such requests are also created with the jQuery.ajax function.

Why is AJAX/JSON response undefined when used in Bootstrap typeahead function?

I created a function that makes a jquery AJAX call that returns a JSON string. On its own, it works fine -- and I can see the JSON string output when I output the string to the console (console.log).
function getJSONCustomers()
{
var response = $.ajax({
type: "GET",
url: "getCustomers.php",
dataType: "json",
async: false,
cache: false
}).responseText;
return response;
};
However, when I set a variable to contain the output of that function call:
var mydata = getJSONCustomers();
, then try to use it within my Twitter-Bootstrap TypeAhead function (autocomplete for forms):
data = mydata;
console.log(data);
I get an 'undefined' error in my console.
Below is a snippet of this code:
$(document).ready(function() {
var mydata = getJSONCustomers();
$('#Customer').typeahead({
source: function (query, process) {
customers = [];
map = {};
data = mydata;
console.log(data);
// multiple .typeahead functions follow......
});
Interesting here, is that if I set the data variable to be the hardcoded JSON string returned from the AJAX function, everything works fine:
data = [{"CustNameShort": "CUS1", "CustNameLong": "Customer One"}]
How can I use the JSON string within my typeahead function?
.responseText returns a string. You have to parse the string first to be able to work with the array:
var mydata = JSON.parse(getJSONCustomers());
That being said, you should avoid making synchronous calls. Have a look at How do I return the response from an asynchronous call? to get an idea about how to work with callbacks/promises.
The problem is that the Ajax request hasn't had the chance to complete before typeahead is initialised, so typeahead is initialised with an uninitialised mydata variable. Also, as of jQuery 1.8+ async: false has been deprecated and you need to use the complete/success/error callbacks.
Try this:
function getJSONCustomers(callback) {
$.ajax({
type: "GET",
url: "getCustomers.php",
dataType: "json",
cache: false,
success: callback
});
};
And then you could do something like:
getJSONCustomers(function(mydata) {
// mydata contains data retrieved by the getJSONCustomers code
$('#Customer').typeahead({
source: function (query, process) {
customers = [];
map = {};
console.log(mydata);
// multiple .typeahead functions follow......
});
});
So your code completes the Ajax call before initialising the typeahead plugin.

get a callback function to add to object javascript

I have an issue with a method ive created for an object ive created. one of the methods requires a callback to another method. the problem is i cant add the data to the object that called the method. it keeps coming back as undefined. otherwise when i send the data to the console it is correct. how can i get the data back to the method?
var blogObject = new Object();
var following = [...];
//get posts from those blogs
blogObject.getPosts = function () {
var followersBlogArray = new Array();
for (var i = 0; i < this.following.length;i++){
var followersBlog = new Object();
// get construct blog url
var complete_blog_url = ...;
i call the getAvatar function here sending the current user on the following array with it.
followersBlog.avatar = blogObject.getAvatar(this.following[i]);
that part goes smoothly
followersBlogArray.push(followersBlog);
}
this.followersBlogArray = followersBlogArray;
}
here is the function that gets called with the current user in following array
this function calls an ajax function
blogObject.getAvatar = function (data) {
console.log("get avatar");
var url = "..."
this ajax function does its work and has a callback function of showAvatar
$(function() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: url,
data: {
jsonp:"blogObject.showAvatar"
}
});
});
}
this function gets called no problem when getAvatar is called. i cant however get it to add the data to the followersBlog object.
blogObject.showAvatar = function (avatar) {
return avatar
}
everything in here works fine but i cant get the showAvatar function to add to my followersBlog object. ive tried
blogObject.showAvatar = function (avatar) {
this.followersBlog.avatar = avatar;
return avatar
}
that didnt work of course. it shows up as undefined. can anyone help?
so somethings like...
$(function() {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: false,
url: url,
complete: function () {
this.avatar = data;
}
data: {
jsonp:"blogObject.showAvatar"
}
});
});
}
Welcome to the world of asynchronous programming.
You need to account for the fact that $.ajax() will not return a value immediately, and Javascript engines will not wait for it to complete before moving on to the next line of code.
To fix this, you'll need to refactor your code and provide a callback for your AJAX call, which will call the code that you want to execute upon receiving a response from $.ajax(). This callback should be passed in as the complete argument for $.ajax().
The correct option for setting the JSONP callback is jsonpCallback. The recommendation from the API for .ajax(...) is to set it as a function.
{
// ...
jsonpCallback: function (returnedData) {
blogObject.showAvatar(returnedData);
},
// ...
}

How to create jquery ajax as separate function?

I want to create a separate function to get specific data from Facebook graph JSON.
For example, I have the load() and called getNextFeed() function.
The getNextFeed works correctly. Except that returning value of aString is not successful.
When I pop alert(thisUrl). It said undefined.
Note: I am new to Javascript and Jquery. Please give me more information where I did wrong. Thank you.
function load()
{
$(document).ready(function() {
var token = "AccessToken";
var url = "https://graph.facebook.com/me/home?access_token=" + token;
var thisUrl = getNextFeed(url);
alert(thisUrl); // return undefined
});
function getNextFeed(aUrl)
{
$.ajax({
type: "POST",
url: aUrl,
dataType: "jsonp",
success: function(msg) {
alert(msg.paging.next); // return correctly
var aString = msg.paging.next;
alert(aString); // return correctly
return aString;
}
});
}
The problem is that $.ajax() is an ansynchronous function, means, when called, it returns in the same instance, but an ajax call is done in a separate thread. So your return vaule of $.ajax() is always undefined.
You have to use the ajax callback function to do whatever you need to do: Basically you already did it correctly, just that return aString does not return to your original caller function. So what you can do is to call a function within the callback (success()), or implement the logic directly within the success() function.
Example:
function load()
{
$(document).ready(function() {
var token = "AccessToken";
var url = "https://graph.facebook.com/me/home?access_token=" + token;
getNextFeed(url);
alert('Please wait, loading...');
});
function getNextFeed(aUrl)
{
$.ajax({
type: "POST",
url: aUrl,
dataType: "jsonp",
success: function(msg) {
alert(msg.paging.next); // return correctly
var aString = msg.paging.next;
alert(aString); // return correctly
do_something_with(aString);
}
});
}

Categories