how to return array from jquery.ajax() - javascript

I have this piece of code:
var suggest=$.ajax({
cache: true,
type: 'GET',
url: solrServer + "suggest?q=" + valore + ec + "wt=json&omitHeader=true&json.wrf=?",
dataType: "jsonp",
success: function (data) {
data = parse();
function parse() {
var parsedQueries = [];
for (var i = 0; i < data.spellcheck.suggestions[1].suggestion.length; i++) {
console.log('i_esimo: ' + data.spellcheck.suggestions[1].suggestion[i]);
parsedQueries[i] = data.spellcheck.suggestions[1].suggestion[i];
}
return parsedQueries;
}
}
});
console.log('suggest: ' + suggest);
when i print in console:
console.log('i_esimo: ' + data.spellcheck.suggestions[1].suggestion[i]);
I visualize all element of response and after i assign it at array parsedQueries, finally return parsedQueries, that should be assigned to my var suggest, but when i print in console suggest, i have:
suggest: [object Object]
and not my array of value. The question is: how do I return an array of values (string) from 'success' of jQuery.ajax() ???

Since ajax is executed asynchronously it is not possible to return a value from ajax request.
One possible solution is to make the request synchronous using the async: false flag, but it is not recommended.
Another solution is to use a callback method, to handle the result of the ajax request

You should JSON encode your array at the server side which will transfer it back as JSON object and mention dataType :'JSON' in your ajax call for this purpose.

Related

AJAX request in ColdFusion

How can I do a AJAX request in ColdFusion?
I have my javascript:
function getdata(){
var formElements=document.getElementById("CFForm_1").elements;
var data=[];
for (var i=0; i<formElements.length; i++){
if(formElements[i].name == 'customersid')
data.push({'customersid':document.getElementById("customersid").value});
if(formElements[i].name == 'customerstoid')
data.push({'customerstoid':document.getElementById("customerstoid").value});
}
$.ajax(
{
type: "get",
url: "components/BillingCalc.cfc",
data: {
method:"ajaxGetTotalCost",
data: data.join()
},
dataType: "json",
success: function( objResponse ){
}
});
}
My component:
component displayName="Calc" {
remote function ajaxGetTotalCost(data){
data = deserializeJSON(arguments.data);
WriteDump(data); abort;
}
I am getting the error: JSON parsing failure at character 2:'o' in [object Object],[object Object]
Does anyone knows how to do AJAX request in CF?
This function:
remote function ajaxGetTotalCost(data){
data = deserializeJSON(arguments.data);
WriteDump(data); abort;
}
is not complete. It's at the stage where you have to call it from a ColdFusion page, not with javascript. That will enable you to see the results of the writedump(data) command to ensure it's what you expect. You have to add more code to the function to get it to produce a variable javascript can receive, and then return that variable to whatever is calling the function.
The issue is related to dataType attribute you are passing with $.ajax() method. dataType: "json" indicates your AJAX request is expecting JSON data as a response. But in your case you are simply returning DUMP of the deserialized JSON, which is HTML not JSON. So if you want it to work properly, then you need to return JSON data from your ColdFusion function. You can try this and see if it works.
remote function ajaxGetTotalCost(data){
data = deserializeJSON(arguments.data);
return serializeJSON(data));
}

blocking javascript execution until response is completed [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
i have js code which returns rows of data for my table. On clicking each of those rows they expand and plan is to show child data of that row by calling another ajax request.
My code for child data looks like below:
function format ( d ) {
var results;
$.ajax({ url: 'http://127.0.0.1:7101/MUDRESTService/rest/v1/feedbacks/' +
d.FeedbackId + '/child/MudFeedbackDetailsVO?onlyData=true',
type: 'get',
dataType: 'json',
success: function(output) {
 console.log(output.items[0].CriticalPath) ;
results = output.items[0];
}
});
return results.CriticalPath;
}
The problem probably is that method doesn't finish by the time value of results.CriticalPath is returned. I can see value in chrome js console so there is no problem with the data part.
So how should i make it return the value once the response is ready
When writing asynchronous code, you need to start working with callbacks rather than return values.
Your functions, like format here, only initiates an action. Updates to the UI are initiated by the callback.
Instead of this logic:
function doSomething() {
var result = format(d);
doSomethingWithResult(result);
}
You need to adapt to this:
function doSomething() {
var result = format(d, doSomethingWithResult);
}
function format( d, callback ) {
$.ajax(..., {
success : function(output) {
var results = output.items[0];
callback(results); // this is where we call doSomethingWithResult
}
});
}
Now I'm no exert at this, but hopefully you'll find something from the code-example that you can use.
I'm binding each row on the .done()-function, which calls another api. I hope this helps.
JS-FIDDLE
(function(){
//getJSON example
var jqxhr = $.getJSON( "https://api.myjson.com/bins/2emll", function(data) {
for (key in data) {
$("#list").append("<li class='" + key + "'>" + data[key] + "</li>");
}
}).done(function( data ) {
$("#list li").on("click", function(e){
var target = e.target.className;
//ajax example
$.ajax({
url: 'https://api.myjson.com/bins/309x5',
type: 'get',
data: target,
dataType: 'json',
success: function(data) {
var title = $("." + target).text();
$("." + target).html(title + '<ul id="ul-' + target + '"></ul>');
}
}).done(function(data){
for (key in data) {
$("#ul-" + target).append("<li class='" + key + "'>" + data[key] + "</li>");
}
});
});
});
})();
you can try setting async option to false
like this
function format ( d )
{
var results;
$.ajax({
url: 'http://127.0.0.1:7101/MUDRESTService/rest/v1/feedbacks/' + d.FeedbackId + '/child/MudFeedbackDetailsVO?onlyData=true',
type: 'get',
dataType: 'json',
async:false,
success: function(output)
{
console.log(output.items[0].CriticalPath) ;
results = output.items[0];
}
});
return results.CriticalPath;
}
NOTE :
but it will make your ajax as synchronous and it may be possible that your browser will be unresponsive for the request so there are some points to be noted before using it
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done() or the deprecated jqXHR.success().
The first letter in Ajax stands for "asynchronous," meaning that the operation occurs in parallel and the order of completion is not guaranteed. The async option to $.ajax() defaults to true, indicating that code execution can continue after the request is made. Setting this option to false (and thus making the call no longer asynchronous) is strongly discouraged, as it can cause the browser to become unresponsive.
fore more information you can read here

Pass a variable to a function from inside an ajax call

I tried to use this loop to read some urls to read their modified time:
var arr = [];
//... fill arr with push
for (var e in arr) {
nodename=arr[e].hostname;
node_json="/nodes/"+nodename;
html +='data';
xhr = $.ajax({
url: node_json,
success: (function(nn) {
$('#host_'+nn).append("last modified: " + xhr.getResponseHeader("Last-Modified"));
})(nodename)
});
This already works a bit i I comment out the success line: I get calls to all node-files, and in Firebug, I can see the different modified times in the header of the calls.
At first I had a closure, (see How to generate event handlers with loop in Javascript?) And I only got the last line modified with all results. that's why I try to put the action in a separate function.
But that gives:
ReferenceError: xhr is not defined
$('#host_'+nn).append("last modified: " + xhr.getResponseHeader("Last-Modified")...
How do I get xhr into that function?
I aslo tried:
...
xhr[e] = $.ajax({
url: node_json,
success: add_result_to_info(nodename, e)
});
}
}
// outside loop
function add_result_to_info(nn, e) {
$('#host_'+nn).append("last modified: " + xhr[e].getResponseHeader("Last-Modified"));
}
source of the AJAX call: Get the modified timestamp of a file with javascript
If arr is truly an array, just use .forEach or even better .map (with a shim on older browsers) to encapsulate each iteration's scope without the need for additional closures:
var xhrs = arr.map(function(e) {
var nodename = e.hostname;
var node_json = "/nodes/" + nodename;
html +='data';
return $.ajax({
url: node_json
}).done(function(data, status, xhr) {
$('#host_'+nodename).append("last modified: " + xhr.getResponseHeader("Last-Modified"));
});
});
The reason to use var xhrs = arr.map() instead of .forEach is that you then (for free) get the ability to call yet another callback once every AJAX request has completed:
$.when.apply($, xhrs).then(function() {
// woot! They all finished
...
});
your are directly executing the method and passing its result as the callback for the success callback.
the xhr is already passed as the 3rd argument so try
success: function(nn,status, xhr) {
$('#host_'+nn).append("last modified: " + xhr.getResponseHeader("Last-Modified"));
}
if you have to pass the nodename as well, the you need to use a function that returns a function
success: (function(nn){
return function(data ,status, xhr) {
// you can use nodename here...
$('#host_'+nn).append("last modified: " + xhr.getResponseHeader("Last-Modified"));
};
})(nodename)

AJAX success function called successfully but does not update page properly

I have the code section below which is a simple AJAX call to retrieve a JSON string from a .ASMX VB .NET Web Method. On success, it calls the createList function below, which should take the values in the JSON string (now parsed and formatted) and add them as new list items.
My issue is that the page does not update with the new list items, even though the callback function is successful. The loop executes, data is received and I have already tested with alerts just to make sure I'm not going crazy.
When I use the exact same line (substituting test data for the JSON string) to append my new list items, everything works fine.
As a side note for anyone that might be wondering why I believe I have to use this methodology:
It is important that I call the AJAX function the way I do, so I may pass multiple parameters to the function when I build the list. The other parameters allow me to specifically find which element is active in my user control.
I am relatively new to using AJAX as well. I hope I was able to explain everything clearly.
Thanks!
function getPcList(activeRow, activeTd) {
var row = $(activeRow).attr("id");
$.ajax({
url: "AJAXWebService.asmx/getPartnerColleges",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(data) {
createList(data, activeRow, activeTd);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
}
function createList(data, activeRow, td) {
var obj = JSON.stringify(eval("(" + data.d + ")"));
var json = $.parseJSON(obj);
var row = $(activeRow).attr("id");
var newtd = $(td).attr("id");
for (i = 0; i < json.length - 1; i++) {
$("#"+row+ "#" + newtd + " > #list > #thelist")
.append("<li id='listitem'" + i +
"' style='width:100%; z-index:300; position:relative' onclick='txtAppend($(this).parents().eq(2))'>" +
json[i] + "</li>");
}
}
If the string returned from the server is a JSON, as indicated by the dataType field of the $.ajax() call, you shouldn't need to use JSON.stringify() and eval(). You should be able to parse the string directly with $.parseJSON().

Javascript Array loses data

I'm having trouble getting my information into an array in an ajax call, if I alert the information right after I insert it into the array it works fine, but if I do it at the end it alerts unidentified. I made sure that books is declared outside so it doesn't interfere.
var books = [];
$.ajax({
url: 'getFolderContents.php',
dataType: 'json',
success: function (data)
{
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
}
},
error: function()
{
alert("error");
}
});
alert(books[0]);
Your
alert(books[0]);
will be executed while the Ajax call is running and therefore will not have any elements at this point of execution yet. Ajax is asynchronous - while you are doing a request to your PHP script your script continues execution.
Put all actions with books in your success function.
Another hint: As of jQuery version 1.8 you cannot longer use the parameter async: false to create a synchronous "A"jax call. You have to use the callback functions. Have a look at the docs for $.ajax
Your array hasn't lost any data; the data hasn't been put in there yet. The 'A' stands for "asynchronous", meaning your success callback hasn't run yet at the time you call the alert.
Put the alert inside your callback instead:
success: function (data)
{
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
}
alert(books[0]);
},
Your alert is executing before the success function is called. Perhaps seeing the same code using a promise will make things clearer.
$.ajax( url: 'getFolderContents.php', dataType: "json" )
//the then function's first argument is the success handler
.then(function( data ) {
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
alert(books[0]
});
});
I always feel this syntax makes async stuff make more sense. Otherwise this code functions exactly like Blazemonger's correct answer.
Your AJAX call is asynchronous, that's why it is undefined.
The alert at the end happens before the ajax success callback, because ajax is asynchronous.

Categories

Resources