generalizing ajax call into function - javascript

I'm trying to attempt to generalize my ajax calls into a function as follows. I have not done this before and am not sure sure if I'm doing it correctly.
<script>
$(document).ready(function(){
var reg_no=$("#reg_no").val();
reg_no=reg_no.trim();
if(reg_no!==""){
//populate fields
data={reg_no:reg_no,func:"getSupplierDetails"};
success_function="updateFormFields";
ajax_call(data,success_function);
}
});
function ajax_call(data,success_function){
$.ajax({
type:"POST",
url:"../control/supplier-c.php",
dataType:"json",
data:data,
success:function(data){
success_function(data); //variable function works??
}
});
}
function updateFormFields(data){
//some code here to handle data array
}
</script>
What I'm trying to do here is avoid rewriting the whole ajax code by passing the data array and the function to be executed on success. What I'm not sure is the use of variable functions as i have done.
A note to be made is that the whole thing works for an ajax call if updateFormFields() code was moved into the success handler in the ajax call and the ajax_call() was not defined as a seperate function but implemented right after the comment "populate fields". I just have no experience in trying it this way and I need to know if this is possible or not.
Thank You

In Javascript, functions are first class objects, meaning you can pass them around as parameters.
function json_post(url, data, success_function, error_function) {
$.ajax({
type:"POST",
url:url,
dataType:"json",
data:data
}).then(success_function, error_function);
}
Then you can call it as
json_post("../control/supplier-c.php", { data: "data" }, function (res) {
console.log('Ajax req successful');
console.log(res);
}, function (res) {
console.log('Error in ajax req');
console.log(res);
});
In your case, you can do:
ajax_call(data, updateFormFields);
and it should work as expected.

There's no need to wrap the success function, you can just apply apply it directly.
function ajax_call(data, success_function) {
$.ajax({
...
success: success_function
});
}
An even better idea is to avoid the legacy success and error callbacks and instead return the jQuery promise. You can use standard promise methods .then() and `.
function ajax_call(data) {
return $.ajax({
...
});
}
ajax_call()
.then(function(data) {
// this runs if it succeeds
})
.fail(function(err) {
// this runs if it failed
});
Promises have a huge benefit to being chain-able, making the code flatter, avoiding the nest of "christmas tree callbacks".

I would recommend checking success_function as well as failure_function to handle server response (XHR) errors also.
function success_function(){
//code to handle success callback
}
function error_function(){
//code to handle failure callback
}
function ajax_call(data, success_function, error_function) {
if (typeof success_function === 'function' && typeof error_function === 'function') {
$.ajax({
type: "POST",
url: "../control/supplier-c.php",
dataType: "json",
data: data,
}).then(success_function).fail(error_function);
}
}

Related

Ajax call with nested ajax calls in for each

I'm experiencing the following problem.
I have the following nested / foreach loops ajax call structure:
var children = [];
$.fn.ajaxHelper.loadAjax({
url: someUrlReturningJsonOfChildren,
cache: true,
callback: function(options) {
var json = options.json;
$.each(json, function (i) {
// get the details of this child
$.fn.ajaxHelper.loadAjax({
url: urlForDetailsUsingId,
cache: true,
callback: function(options) {
var json = options.json;
children[i] = json;
}
});
}
}
});
// want to do something with (newly filled) children here
As you can imagine, I'm running into the trouble that the ajax calls are asynchronous (duh), but I want to do something with the children array only when all the ajax calls are done. Otherwise I'm obviously dealing with an incomplete array.
I have been looking at some jQuery solutions such as Deferred objects (using $.when().then() and such), but that would only solve the problem if I would not have the foreach-loop (as far as I can tell).
Also, changing the REST API (where the ajax calls are going) is not an option unfortunately, due to specified requirements regarding the API.
Ok, so without further ado: can anyone of you geniuses help me with this? :-)
ajax is asynchronous by default but you can turn it off. Here goes the API on how to do it
https://api.jquery.com/jQuery.ajax/
heres a little demp
$.ajax({
url: my_url.php,
type: "POST",
async: false,
dataType: 'json'
});
Or just make your next ajax call in a success function (Recommended)
function testAjax(handleData) {
$.ajax({
url:"getvalue.php",
success:function(data) {
//next ajax call here
}
});
}
You must run ajax query when previous query is completed with success (in jQuery onSuccess callback)
I had a smiler issue... below is a simplified version of my solution.
Step one: Declare global variables.
var results1,
results2,
[resultsN];
Step two: Make a function that accepts the results of each AJAX call as parameters.
function foo(results1, results2, [resultsN]) {
if (results1, results2, [resultsN]) {
//... do whatever you want with all of your results
}
}
Step three: Call all of the AJAX functions, set results to global variables, and call function foo for each.
function ajax() {
//AJAX call 1
$.ajax({
type: 'POST',
url: //URL,
success: function (data, textStatus, jqXHR) {
results1 = data;
},
dataType: 'json',
complete: function () {
foo(results1, results2);
}
});
//AJAX call 2
$.ajax({
type: 'POST',
url: //URL,
success: function (data, textStatus, jqXHR) {
results2 = data;
},
dataType: 'json',
complete: function () {
foo(results1, results2);
}
});
};
This method has the advantage of running as fast as the longest AJAX call takes. If you simply nest AJAX queries in the complete event then you will have to wait for each AJAX call to complete before moving to the next one...

function and defered jquery

Hello i'm very confused on this argument: I know that in javascript function executes in an
asyncronous way sometimes and here is my problem. i have a function called
function createPopupHour()
this function creates an html select element and it doesn't return nothing. I call this function in a $.AJAX request in the success part of the request.
$.ajax({
url:"responseregistrodocente.php",
data:{
operazione:'caricaAssenza',
idAssenza:id_array[3],
codiceFiscale: id_array[0],
data:id_array[1],
tipo:id_array[2]
},
type:"POST",
dataType:"json",
success: function (jsonObject) {
createPopupHourSelect()
//other code
});
},
error: function(error){
//XMLREQQUESTOBJECT
alert(error.responseText);
location.reload();
},
cache:false,
ifModified:false
});
the problem is that when i call the function the other code doesn't attent that my function end. i know that in jquery there is the "deferred Object",maybe i need that my function create a deferred object, and return it to the code. but how is the sintax:? or is there another more easy and dry solution???
is correct something like this?
function createPopupHour select(){ //staff to do
return $.deferred();//it's in pending state
}
and $.ajax
$.ajax({
url:"responseregistrodocente.php",
data:{
operazione:'caricaAssenza',
idAssenza:id_array[3],
codiceFiscale: id_array[0],
data:id_array[1],
tipo:id_array[2]
},
type:"POST",
dataType:"json",
success: function (jsonObject) {
var defered=createPopupHourSelect()
defered.then(function{//other code])
defered.resolve();
});
},
error: function(error){
//XMLREQQUESTOBJECT
alert(error.responseText);
location.reload();
},
cache:false,
ifModified:false
});
Yes, the other code needs to reside in a callback function that will be executed when popup thing is done, just like the popup startup code is executed when the ajax is done. You can either use a primitive callback, or use the more powerful promise pattern.
The syntax for jQuery Deferred objects is
function …() {
var def = $.Deferred();
// start asynchronous task
// when the task is done (in the future), call
def.resolve(…); // optionally with results
// and right now do
return def.promise();
}
Since $.ajax does return a promise as well, you can use chaining via .then (assuming createPopUpHourSelect is in the above pattern):
$.ajax({
url:"responseregistrodocente.php",
data:{…},
type:"POST",
dataType:"json",
cache:false,
ifModified:false
})
.fail(function(error){
alert(error.responseText);
location.reload();
})
.then(createPopupHourSelect) // gets passed the parsed JSON
.then(function(result) { // gets passed the resolve arguments from the popup
// other code
});
If you need the ajax response in the other code as well and don't want to pass it through the popup function, use
.then(function(json) {
return createPopupHourSelect(…)
.then(function(popupResults) {
// other code
});
}) /* returns a promise that resolves with result of other code
.then(…) */

how to use properties and methods withing a JavaScript class to exchange data?

i have small issue with exchanging data in between methods in a JavaScript object (class):
var TEST = (function () {
var TEST = function() {
};
TEST.prototype.get = function() {
$.ajax({
type: "GET",
url: "http://test.com/getall",
dataType: "json",
success: function (data) {
return data; // if i console log this i will get a json obj
}
});
};
TEST.prototype.parse = function(data) {
$.each(this.get(), function(k, v){
console.log(v);
});
};
return TEST;
})();
so i am trying to call one method in the each statement in another method. the issue is that
the response is undefined.
i also tried it like this, but with he same result
var testing = new TEST();
var get = testing.get();
testing.parse(get);
What am i missing? how can i return the data from this.get to be used in this.parse.
thanks
$.ajax() per default is asynchronous. That means, that the execution of your function get() wont wait until the request is finished. Hence you return no value from it, which results in undefined being returned.
In order to have your get() function be able to return a value, you would have to do the request in a synchronous way and set a variable in the outer function (as success itself is just another function, whose return value is not caught):
TEST.prototype.get = function() {
var result;
$.ajax({
type: "GET",
url: "http://test.com/getall",
async: false, // this is the important part!
dataType: "json",
success: function (data) {
result = data;
}
});
return result;
};
EDIT
As mentioned by #pebbl, this will halt the execution of all your scripts, until the request is done. Hence your whole page will be blocked for the time being.
The general approach is to use callbacks in such cases, which will be executed once the requests finished. So in your case something like this:
TEST.prototype.get = function( cb ) {
$.ajax({
type: "GET",
url: "http://test.com/getall",
dataType: "json",
success: function (data) {
cb( data );
}
});
};
with later on calling like this:
var testing = new TEST();
testing.get( function( data ) {
testing.parse( data );
});
You can't construct your function this way as you are relying on an asyncronous call, which will return it's result outside of the normal execution flow. The only way you can actually receive the result of your .get function is to use a callback.
Put simply your value isn't being returned from the .get function, it's being returned from the callback you are passing into jQuery's .ajax method.
You'd be far better off redesigning your code so as to still support the asyncronous call -- rather than disabling async.
A rough idea is to change your parse function like so:
TEST.prototype.parse = function(data) {
this.get(function(result){
$.each(result, function(k, v){
console.log(v);
});
});
};
And to change your get function accordingly:
TEST.prototype.get = function(callback) {
$.ajax({
type: "GET",
url: "http://test.com/getall",
dataType: "json",
success: callback
});
};
The above is just a quick example, you'd be wise reading up on the following jQuery topics:
http://api.jquery.com/promise/
http://api.jquery.com/category/deferred-object/
If you design your code around the promise pattern you'll find it complicated at first, but it gives you a lot of power in your code -- and gets around the whole callback stacking madness you can end up with when dealing in ajax calls.
Whilst it's not entirely clear from the jQuery.ajax documentation, this function returns a jqXHR object which implements the promise interface. So this means you can use the promise methods done, always and fail.
http://api.jquery.com/jQuery.ajax/

waiting for an ajax reply

I have a javascript function called GetRequest() that calls the server with $.ajax() and receives a json string:
function GetRequest(ThePage) {
RequestedPage = parseInt(ThePageNumber,10);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "../Pages/MyPage.aspx/GetPage",
data: "{'ThePage':'" + ThePageNumber + "'}",
dataType: "json",
success: function (msg) {
var data = msg.hasOwnProperty("d") ? msg.d : msg;
OnSucessCallBack(data);
},
error: function (xhr, status, error) {
alert(xhr.statusText);
}
});
};
I have a function called ShowData() that calls GetRequest() and must wait until GetRequest receives its data before continuing.
function ShowData() {
//some code that determines the page number
GetRequest(ThePageNumber);
//wait until the data is in
};
I use GetRequest in several places so I can't use its success function in the context of ShowData.
How do I make my function ShowData pause its execution until GetRequest is finished? I thought of changing the OnSuccessCallBack function and determine which function initially called GetRequest() but I'm not sure on how to best do this.
Thanks for your suggestions.
add a function pass-in to GetRequest like so:
function GetRequest(pageNumber, successCallback){
//I admit this isn't "elegant" but it's most assuredly readable
var callback;
if (successCallback == null) {
callback = //default callback definition here
} else {
callback = successCallback;
}
//do everything else the same here
//except use the callback defined above
}
This gives you the flexibility to add in a separate callback handler for the onsuccess
Alternately, do the same as above, but use the "onComplete" handler unless you need the data specifically on the return (it doesn't appear as tho you do).
I'm going to strenuously suggest that you do use callbacks for asynchronous code instead of trying to shoehorn in sync requests. It's much better to just adopt a coding style that revolves around async requests when working in javascript, especially where you're already doing AJAX (which is by definition intended to be async).
Pass async:false along with the ajax options..
$.ajax({
type: "POST",
async:false,
.
.
.
});
You can make your call only synchronous by using ajax prefilters:
function ShowData() {
//some code that determines the page number
$.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
options.async = false;
});
GetRequest(ThePageNumber);
//wait until the data is in
};

How to return the result from JSONP call outside the function?

I have the following function which works great, i used JSONP to overcome cross-domain, wrote an http module to alter the content-type and didn't append a callback name in the url.
function AddSecurityCode(securityCode, token) {
var res=0;
$.ajax({ url: "http://localhost:4000/External.asmx/AddSecurityCode",
data: { securityCode: JSON.stringify(securityCode),
token: JSON.stringify(token)
},
dataType: "jsonp",
success: function(json) {
alert(json); //Alerts the result correctly
res = json;
},
error: function() {
alert("Hit error fn!");
}
});
return res; //this is return before the success function? not sure.
}
the res variable is alwayes comes undefined. and i can't use async=false with jsonp.
so how can i return the result to outside the function??
and i sure need to do that for subsequant calls.
Please advice, thanks.
The problem is i can't return the result value outside this function
You simply cannot do this.
You have to rewrite your code flow so that AddSecurityCode takes a callback parameter (i.e. a function to run) that you then invoke inside your success callback:
function AddSecurityCode(securityCode, token, callback) {
$.ajax({
....
success: function(json) {
alert(json); //Alerts the result correctly
callback(json); // HERE BE THE CHANGE
}
....
});
}
You have res declared inside the function, making it's scope local to that function. So there's a start. Declare res outside the function and see what happens.
Add async: false to the ajax request object
$.ajax({
...
async: false,
...
});
return res;
But this is not recommended since it will block the browser and will seen as not responding until the ajax call completed. Async process should use callback function like the other answer mentioning

Categories

Resources