jQuery call stack? - json

I have many instances of the same type of problem using jQuery. Probably because I am missing some basic knowledge (jQuery newb). In my $.Ajax calls to get data - on the success: I perform many calls to other functions based on the data that gets returned. The calls need to be made in a specific order but this does not seem to happen. If I have a call to another jQuery function that I wrote and then three line later have a call to yet another function (which depends on some events that happen in the first function call) the second call is happening first. Ran this with debugger set many times in two different $.Ajax calls and it happens this way. Am I doing something completely wrong?
BTW - the data is coming in just fine and populating my table and form items. Per request I am posting code below - the comments show that GetInventory needs to execute before BuidlNav
$(document).ready(function () {
$('#searchNow').css('visibility', 'hidden'); //Hide Search Now button
$("#popup").css("display", "none");
$('#submit').prop('disabled', true);
$.ajax({
type: "POST",
url: "mypage.aspx/mywebmethod",
contentType: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
success: function (states) {
var jsonCodes = JSON.parse(states.d);
for (var i in jsonCodes) {
$("#Select0").append(new Option(jsonCodes[i].regionname, jsonCodes[i].region_id));
}
var first = getUrlVars()["region"];
if (first) {
debugger;
$.fn.SetAllSelectors(reg);
$.fn.GetInventory(1, 10, reg, 'rank', 'asc'); //This should happen first
$.fn.BuildNav(); // This depends on GetInventory having been executed already.
}
else {
var myText = 'United States';
$("#Select0 option").filter(function () {
return $(this).text() == myText;
}).first().prop("selected", true);
$.fn.GetChildRegions("Select0");
}
}
});
}
);

If GetInventory and BuildNav also use ajax, you'll need a structure more like this. When making ajax calls, the data is fetched while not holding up the next command line, so chances are your 2nd or 3rd function is being called before the first finishes.
$.ajax({
type: "POST",
url: "mypage.aspx/mywebmethod",
contentType: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
success: function (states) {
getInventoryAndBuildNav(states);
},
...
});
function getInventoryAndBuildNav(states){
$.ajax({
....
url: "mypage.aspx/getinventory",
success: function (inventory) {
$.fn.BuildNav();
},
...
});
}
The best way to accomplish this is to build functions for each item and allow a callback method to be passed.
Think of it this way
$.ajax({
type: "POST",
url: "mypage.aspx/mywebmethod",
contentType: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
success: function (states) {
//This will trigger second since we had to wait for the process to finish
alert('The Ajax call has been made, finished, and the data received');
}
});
//This will trigger FIRST since the ajax call was initiated, but we're still waiting
alert('The Ajax call has been made. We're moving on to the next call.');

Related

How to make sure an ajax call's result arrived before starting the next one while both are binded to the same onclick?

I have 2 ajax calls, the second needs the first's result as input. My problem is that I want to call both of them at the same click. And however I tried I can't manage to get the first's result before the second starts.
If I create a second button and manually make the delay everything works. I tried to call a third function with sleep between the two functions but even that didn't work. Any idea would be very helpful, thank you! I bind the two functions two the button's onclick through a third function.
sendSearchToDB = event => {
$.ajax({
url: 'https://localhost:44348/api/user/GetUsers',
type: 'POST',
data: JSON.stringify(this.state.searchExpression),
contentType: 'application/json',
dataType: 'json',
async: false,
success: (data) => {
this.setState({peoples: data})
}});
}
The second ajax:
getBoolArray = event => {
let string = this.props.email
this.state.peoples.forEach(item => {
string = string + "$" + item.id
});
$.ajax({
url: 'https://localhost:44348/api/user/PendingFriendRequest',
type: 'POST',
data: JSON.stringify(string),
contentType: 'application/json',
dataType: 'json',
async: false,
success: (data) => {
this.setState({boolArray: data})
}});
}
Call the second ajax call within the success of the first ajax call. In this way you will get the result of first one and pass it to the second one

jQuery button don't change its class instantly because of AJAX call

When my button is clicked,I want to change it's class instantly,but it seems that the ajax call is not letting it to happen.It's happening 3-4 seconds later.Why?I tested with alerts and it's ok.
the button:
$('#myButton').click(function() {
alert("ok");//it will alert instantly
$('#myButton').removeClass().addClass("btn btn-success"); //here, this code is running after 3-4 secs
});
ajax call:
$('button').click(function() {
...some code...
$.ajax({
async: false,
type: 'POST',
dataType: 'json',
url: myUrl,
data: myValue,
success: function(data) {
setTimeout(function() {
img.src = img.src;
}, 10);
}
})
}
Without the ajax call it works
Remove this:
async: false
Adding that makes the asynchronous operation artificially synchronous, blocking everything else from happening in the browser. You're probably even getting a warning about deprecation in your browser's development console.
Never use async: false. Keep asynchronous operations asynchronous.

creating an array and sending to ajax

I'm trying to gather information from all of the textareas on my page, and then put that information into an array so I can send to the server via ajax/json.
Although I am not quite sure how to go about doing it.
I'm not sure how to pull the information I need from the
Here is what I have so far:
Example of my HTML
"<textarea id='tbObjective_" + counter + "' name='txtObjective' class='objectives' sequence='" + counter + "'></textarea>"
jQuery:
var objectiveList = [];
$('.objectives').each(function (objective) {
objectiveList.push({
id: objective.id,
sequence: objective.sequence,
text: objective.val()
});
});
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: objectiveList
});
Any help would be appreciated
Thanks
you can proceed with the following procedure. i have used python django and html5 for the purpose
1. make a text box which is hidden and after generating your json document set it in this text box (suppose id of textbox is "submit_json") than use
$("#submit_json").val(JSON.stringify(formData, null, '\t')), // (formData, null, '\t') this is js function that i have written for the ourpose
data = JSON.stringify({"jsonDoc":Generated JSON})
console.log(data);
$.ajax({
url: 'http://127.0.0.1:8000/catchjson/',
type: 'POST',
async: false,
contentType: 'application/json',
data: data,
dataType: 'json',
processData: false,
success: function(data){
alert('Done')
//Goto Next Page
},
error: function(jqXHR, textStatus, errorThrown){
alert("Some Error!")
}
})
Now on server you can catch this json if u have problem creating json from your text box let me know
I often use:
var formData = $("form").serialize();
for posting data over ajax, so maybe you could try:
var textareaData = $(".objectives").serialize();
$.ajax({
type: "POST",
url: url,
dataType: "json",
data: textareaData
});
or alternatively make sure all the fields are in a form element and use the first example.
You can parameterise it with $.param(objectiveList)
see jQuery.param()

$.post() behaves different than $.ajax( same paramenters )

I came across something weird, that I want to expose and know if someone as an explanation for it.
Some time back i had a simple post:
$.post("/Route/Save", { myObj: JSON.stringify(myObj), accessToken: getAccessToken()}, function(data)
{
//do stuff
});
and it was working nicely, now doesn't work, and only the accessToken paramenter is correctly received in the route controller
I changed it to:
$.ajax({
url: "/Route/Save",
data: '{ myObj:' + JSON.stringify(myObj) + ',accessToken:"' + getAccessToken()+'"}',
type: 'POST',
datatype: 'JSON',
contentType: 'application/json',
success: function (data)
{
//Do stuff
}
});
And now it works. I'm using firefox 4 and IE9 and believe the reason is connected to the way the browser is sending the info encoded... in the $.post() case it looks like it sends the data as application/x-www-form-urlencoded
I'll be glad to hear from you guys!
Regards,
byte_slave
I'm not sure why it was working before; perhaps a jQuery update changed behaviour?
As to your question on the content-type, $.post is a shorthand wrapper around $.ajax, and from the $.ajax api page, the default value for the contentType is 'application/x-www-form-urlencoded'.
AFAIK, you can't specify the contentType using $.post(). I could be wrong though.
The equivalent with $.ajax should be
$.ajax({
url: "/Route/Save",
data: { myObj: JSON.stringify(myObj), accessToken: getAccessToken()},
type: 'POST',
success: function (data)
{
//Do stuff
}
});

how to return ajax suceess from user defined function [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I am having the bellow function .
Here i want to return ajax success from user defined function . How to do this
alert(Ajaxcall(id_array,"del"));
function Ajaxcall(id_array,type){
$.ajax({
type: "POST",
url: "serverpage.php",
cache:false,
data: ({id:id_array,type:type}),
success: function(msg){
return msg; //this returns nothing
}
});
alert(msg); // this one undefined
}
thanks
The "a" in "ajax" stands for "asynchronous" ("Asynchronous JavaScript And XML", although these days most people use it with JSON rather than XML).
So your Ajaxcall function returns before the ajax call completes, which is why you can't return the message as a return value.
The usual thing to do is to pass in a callback instead:
Ajaxcall(id_array,"del", functon(msg) {
alert(msg);
});
function Ajaxcall(id_array,type, callback){
$.ajax({
type: "POST",
url: "serverpage.php",
cache:false,
data: ({id:id_array,type:type}),
success: function(msg){
callback(msg);
}
});
}
It's surprisingly easy with JavaScript, because JavaScript's functions are closures and can be defined inline. So for instance, suppose you wanted to do this:
function foo() {
var ajaxStuff, localData;
localData = doSomething();
ajaxStuff = getAjaxStuff();
doSomethingElse(ajaxStuff);
doAnotherThing(localData);
}
you can literally rewrite that asynchronously like this:
function foo() {
var localData;
localData = doSomething();
getAjaxStuff(function(ajaxStuff) {
doSomethingElse(ajaxStuff);
doAnotherThing(localData);
});
}
I should note that it's possible to make an ajax call synchronous. In jQuery, you do that by passing the async option in (setting it false). But it's a very bad idea. Synchronous ajax calls lock up the UI of most browsers in a very user-unfriendly fashion. Instead, restructure your code slightly as above.
But just for completeness:
alert(Ajaxcall(id_array,"del"));
function Ajaxcall(id_array,type){
var returnValue;
$.ajax({
type: "POST",
url: "serverpage.php",
cache:false,
async: false, // <== Synchronous request, very bad idea
data: ({id:id_array,type:type}),
success: function(msg){
returnValue = msg;
}
});
return returnValue;
}
JQuery has a number of global Ajax event handlers, including $.ajaxComplete() and $.ajaxSuccess() (ref: http://api.jquery.com/ajaxSuccess/).
The code can be attached to any DOM element and looks like this:
/* Gets called when all request completes successfully */
$("#myElement").ajaxSuccess(function(event,request,settings){
$(this).html("<h4>Successful ajax request</h4>");
});
This code will execute whenever any successful Ajax call is completed.