Design to block asynchronous javascript - javascript

var flow;
$.ajax({
url: "qa/version.json",
dataType: "json",
success: function( response ){
flow = response.Version;
}
});
$(".flow").append(flow);
Due to the nature of JS asynchronous design, the append would will be execute before it is being assigned a value in ajax call. What is the best way to tell the script to wait until flow gets assigned in ajax call, then do the append? I do not want to put append right below the success, I would like to keep them separate.

The "best way" is to perform the action in response to the asynchronous action:
$.ajax({
url: "qa/version.json",
dataType: "json",
success: function(response){
$(".flow").append(response.Version);
}
});
If you want to "keep them separate" then you can define a function to call in the response:
var appendFlow = function (flow) {
$(".flow").append(flow);
};
$.ajax({
url: "qa/version.json",
dataType: "json",
success: function(response){
appendFlow(response.Version);
}
});
Separating the code into its own function is simply a matter of organizing your code into re-usable components. Either way, by design the response can't be processed until it's received, so you'd perform your actions in response to the asynchronous call.

Anything wrong with:
$.ajax({
url: "qa/version.json",
dataType: "json",
success: function( response ){
flow = response.Version;
$(".flow").append(flow);
}
});

I have no idea why you don't want to put your success handler in the spot for a success handler, but here's an alternative that may help you.
jQuery returns a Deferred instance when you make AJAX requests. You can use its .done() method to set up a callback later.
var dfd = $.ajax( /* your code here, without the success handler */);
// later on...
dfd.done(function (response) {
$('.flow').append(response.Version);
});
See also:
https://api.jquery.com/deferred.done/
https://api.jquery.com/jquery.deferred/

Or:
var request = $.ajax({
url: "qa/version.json",
dataType: "json"
});
request.done(function(response){
$(".flow").append(response.Version);
});

Related

How to put ajax request inside function and call it when necessary?

I have an ajax request:
$.ajax({
type: 'POST',
url: '/get-result.php',
dataType: 'json',
data: 'pid=' + $(this).attr("id"),
success: function(response) {
$(".reviewee-fname").append(response['fname']);
$(".reviewee-lname").append(response['lname']);
} }); };
I want to be able to put this inside a function that waits for me to trigger it with a return call. I am not exactly sure how to word it, I am new to javascript and jquery. But basically, I want to trigger this ajax call with various different button clicks and instead of having to put the ajax call inside every button click event, I want to put it in a stand alone function so if I ever update it later I dont have to change it 5 times.
Heres an example of a click event Id like to call the ajax request function with. Thanks!
$(function() {
$(".task-listing").click(function() {
//Call Ajax function here.
});
});
Callbacks are well-suited for this scenario. You can encapsulate your ajax call in a callback function.
function apiCall() {
$.ajax({
type: 'POST',
url: '/get-result.php',
dataType: 'json',
data: 'pid=' + $(this).attr("id"),
success: function(response) {
$(".reviewee-fname").append(response['fname']);
$(".reviewee-lname").append(response['lname']);
} }); };
}
You can now hook apiCall()method as a callback to button click.
$(function() {
$(".task-listing").click(apiCall);
});
By doing this you will able to achieve this.
I want to put it in a stand alone function so if I ever update it later I dont have to change it 5 times.
EDIT:
Note:
This is lead to start, you can alter this according to your requirement.
Is this not working for you? ↓↓
$(function() {
$(".task-listing").click(function() {
let pid = $(this).attr("id"); //get any other value which you want to pass in function, say url
someFunction(pid); // pass any other parameters, eg- someFunction(pid, url)
});
});
function someFunction(pid){ // someFunction(pid, url)
$.ajax({
type: 'POST',
url: '/get-result.php', // url: url
dataType: 'json',
data: 'pid=' + pid,
success: function(response) {
$(".reviewee-fname").append(response['fname']);
$(".reviewee-lname").append(response['lname']);
}
});
}

unable to show record using webservice

this code is working fine but not showing records. in alert if i am getting record from file its working fine.
$j().ready(function(){
var result =$j.ajax({
type: "GET",
url: "webService address",
dataType :'json',
contentType:'application/json; charset =utf-8',
success:function(data)
{
$j.each(data, function(index,element){
alert("Successful here: "+element);
});
}
});
alert("result"+result);
});
Welcome to the wonderful world of asynchronous ...
First of all, jQuery get doesn't return the data, that needs to be handled by the callback (which is working as from your post)
var result = null;
$j(document).ready(function(){
$j.ajax({
type: "GET",
url: "webService address",
dataType :'json',
contentType:'application/json; charset =utf-8',
success:function(data)
{
result = data;
$j.each(data, function(index,element){
alert("Successful here: "+element);
});
}
});
alert("result"+result);
});
This might not work as well since jQuery ajax is asynchronous and the alert may pop up while the GET is still reading data and not yet ready !!!!
Check Jquery ajax doc:
$.ajax({
type: "GET",
url: "webService address",
dataType :'json',
contentType:'application/json; charset =utf-8'
}).done(function(data) {
console.log(data);
});
The javascript is not waiting AJAX to finish, it moves on. That is why its called asynchronous . If you need synchronous call, use async: false.

Trigger success handler is finished executing, with nested ajax requests

I have many nested ajax requests like below. I have a lot of things going on in the success function below, I need something like success that will trigger when success is complete. complete(jqXHR, textStatus) just seems to fire with success and I don't think .ajaxComplete() works.
$.ajax({
url: 'api/periods.json',
dataType: 'json',
success: function (d1) {
//more nested ajax requests
},
});
SOLUTION:
A $.ajax() replacement plugin called $.fajax() (finished + ajax) has been created. Please check it out and let me know what you think. https://github.com/reggi/fajax (It's pretty well documented).
You could create a wrapper function for jQuery.ajax to make this a little cleaner:
var started = 0, done = 0;
var globalHandler = function(){
//do stuff when all success handlers are done
}
function handleAjax(args){
var _success = args.success || function(){};
args.success = function(jqXHR, textStatus){
_success(jqXHR, textStatus);
done++;
if(done >= started)
globalHandler();
}
var ajax = $.ajax(args);
started++;
return ajax;
}
usage
handleAjax({
url: 'api/periods.json',
dataType: 'json',
success: function (d1) {
//more nested ajax requests like this:
handleAjax({...});
}
});
This creates a closure so don't do any crazy memory-intensive stuff in there and you should be fine.
I'm not quite totally sure of what you're asking, so forgive me if I'm off-kilter, but I think you might want something like:
$.ajax({
url: 'api/periods.json',
dataType: 'json',
success: function(d1){
//more nested ajax requests
},
}).done(function(msg){
alert("Every Ajax Call is Complete!");
});
You may want .queue() or .Defered
$("#el").queue("queue_name",function(){
$.ajax({
url: 'api/periods.json',
dataType: 'json',
success: function(d1){
//more nested ajax requests
$("#el").dequeue("queue_name"); // tell queue success is complete
},
});
}).queue("queue_name",function(){
//do something you want when success is complete
})
$("#el").dequeue("queue_name"); // start to execute
or $.Deferred()
$.ajax({
url: 'api/periods.json',
dataType: 'json',
success: function(d1){
var start = function(){
var dtd = $.Deferred();
//more nested ajax requests---------------
$.post("xxx",function(){
dtd.resolve(); // when success is complete
});
//----------------------------------------
return dtd.promise();
}
start.apply(this).pipe(function(){
//do something you want when success is complete
});
},
});

problem in accesing a variable outside of a function in ajax call

$.getJSON("http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=100&q="+query+"&json.wrf=?", function(result){
//$.each(result.response.docs, function(result){
if(result.response.numFound==0)
{
$.ajax({
url: "http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=100&q="+query+"&spellcheck=true&json.wrf=?",
async:false,
success: function(result){
$.each(result.spellcheck.suggestions, function(i,item){
newquery=item.suggestion;
});
}
});
}
I posted question related to this problem previously: Problem in accessing a variable's changed value outside of if block in javascript code and i got that i have to make ajax call async. So i did like the above code, but still i am not getting updated newquery outside of if block. still it is showing the old value of newquery.
please suggest where i ma doing wrong
edit
$(document).ready(function(){
// This function get the search results from Solr server
$("#submit").click(function(){
var query=getquerystring() ; //get the query string entered by user
// get the JSON response from solr server
var newquery=query;
$.getJSON("http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=100&q="+query+"&json.wrf=?", function(result){
//$.each(result.response.docs, function(result){
if(result.response.numFound==0)
{
$.ajax({
url: "http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=100&q="+query+"&spellcheck=true&json.wrf=?",
async:false,
dataType: 'json',
success: function(json){
$.each(json.spellcheck.suggestions, function(i,item){
newquery=item.suggestion;
});
}
});
}
$.getJSON("http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=20&q="+newquery+"&sort=price asc&hl=true&hl.fl=description&hl.usePhraseHighlighter=true&json.wrf=?", function(result){
Now as i want to use this updated newquery in $getjosn() if result.response.numFound==0,otherwise newquery will hold the old value
Try this:
$(document).ready(function(){
// This function get the search results from Solr server
$("#submit").click(function(){
var query=getquerystring() ; //get the query string entered by user
var newquery=query;
$.getJSON("http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=100&q="+query+"&json.wrf=?", function(result){
if(result.response.numFound==0)
{
$.ajax({
url: "http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=100&q="+query+"&spellcheck=true&json.wrf=?",
async:false,
dataType: 'json',
success: function(json){
$.each(json.spellcheck.suggestions, function(i,item){
newquery=item.suggestion;
});
$.getJSON("http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=20&q="+newquery+"&sort=price asc&hl=true&hl.fl=description&hl.usePhraseHighlighter=true&json.wrf=?", function(result){
}
});
}
}else{
$.getJSON("http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=20&q="+newquery+"&sort=price asc&hl=true&hl.fl=description&hl.usePhraseHighlighter=true&json.wrf=?", function(result){
}
The $.ajax(...) call returns immediatly. The success function is a callback function which means that this function is called when the ajaxrequest completes. If you want to change something with the new values recieved you have to do that in the success function.
A second point is, you overwrite your value for newquery with each loop, so newquery will only hold the last element of your result.speelcheck.suggestions list. Not sure if that is what you want.
You are redefining 'result' in the ajax() success function. Change this, and then work on fixing your problem :)
You want to call the getJSON() function within the success function of the $.ajax() request. The success() event isn't called until the data has been returned, this won't happen straight away, and so the final getJSON() event will fire before this.
Moving the getJSON() function to the end of the $.ajax() success function will resolve your problem.
Ensure it's outside the $.each() statement.
new answer based on answer from michael wright:
$(document).ready(function(){
// This function get the search results from Solr server
$("#submit").click(function(){
var query=getquerystring() ; //get the query string entered by user
var newquery=query;
$.getJSON("http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=100&q="+query+"&json.wrf=?", function(result){
if(result.response.numFound==0)
{
$.ajax({
url: "http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=100&q="+query+"&spellcheck=true&json.wrf=?",
async:false,
dataType: 'json',
success: commonSuccess});
}else{
$.getJSON("http://192.168.1.9:8983/solr/db/select/?wt=json&&start=0&rows=20&q="+newquery+"&sort=price asc&hl=true&hl.fl=description&hl.usePhraseHighlighter=true&json.wrf=?", commonSuccess);
}
//...
}); //End of $(document).ready(...)
function commonSuccess(json){
//do onSuccess for all queries
}

How to call second jQuery.ajax instance on success of first and update page

I have some jQuery that is triggered on click of a link with the class 'changetag'. I'm using $.ajax() to update the database via changetag.php.
I then change the visual appearance of the link by toggling the class between on/off. The code is as follows:
$(function() {
$(".changetag").click(function(){
var element = $(this);
var I = element.attr("id");
var info = 'switch_tag=' + I;
$.ajax({
type: "POST",
url: "_js/changetag.php",
data: info,
success: function(){}
});
$("#li_"+I).toggleClass("off on");
element.toggleClass("off on");
return false;
});
});
Works perfectly. But now I want to add in a second PHP call which will pull data and update another area of the page if the above was successful.
What I'm trying to add is:
$.ajax({
url: "_js/loaddata.php",
success: function(results){
$('#listresults').empty();
$('#listresults').append(results);
}
});
But just adding it into success: function(){} doesn't seem to be working. To clarify, here is the complete code I'm testing:
$(function() {
$.ajaxSetup ({cache: false});
$(".changetag").click(function(){
var element = $(this);
var I = element.attr("id");
var info = 'switch_tag=' + I;
$.ajax({
type: "POST",
url: "_js/changetag.php",
data: info,
success: function(){
$.ajax({
url: "_js/loaddata.php",
success: function(results){
$('#listresults').empty();
$('#listresults').append(results);
}
});
}
});
$("#li_"+I).toggleClass("off on");
element.toggleClass("off on");
return false;
});
});
The PHP scripts are both called successfully and the toggle class works, but the data pulled is not written to #listresults for some reason.
Ajax calls are (by default) asynchronous. That means that this code:
$("#li_"+I).toggleClass("off on");
element.toggleClass("off on");
return false;
could be executed before the ajax call preceding it is finished. This is a common problem for programmers who are new to ajax and asynchronous code execution. Anything you want to be executed after the ajax call is done must be put into a callback, such as your success handler:
$.ajax({
type: "POST",
url: "_js/changetag.php",
data: info,
success: function(){
$("#li_"+I).toggleClass("off on");
element.toggleClass("off on");
}
});
Likewise, you could put the second ajax call in there as well:
$.ajax({
type: "POST",
url: "_js/changetag.php",
data: info,
success: function(){
$("#li_"+I).toggleClass("off on");
element.toggleClass("off on");
$.ajax({
url: "_js/loaddeals_v2.php",
success: function(results){
$('#listresults').empty();
$('#listresults').append(results);
}
});
}
});
With jQuery 1.5's Deferred Object, you can make this slicker.
function firstAjax() {
return $.ajax({
type: "POST",
url: "_js/changetag.php",
data: info,
success: function(){
$("#li_"+I).toggleClass("off on");
element.toggleClass("off on");
}
});
}
// you can simplify this second call and just use $.get()
function secondAjax() {
return $.get("_js/loaddata.php", function(results){
$('#listresults').html(results);
});
}
// do the actual ajax calls
firstAjax().success(secondAjax);
This is nice because it lets you un-nest callbacks - you can write code that executes asynchronously, but is written like synchronously-executed code.
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are removed as of jQuery 3.0. You can use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
https://api.jquery.com/jQuery.ajax/#jqXHR

Categories

Resources