use different parameter for a success callback - javascript

I'm working on someone else's code. I have this simple AJAX call in jQuery:
function getWSData (which, data, idVR)
{
if(which == 'verCandAll')
{
funcSuccess = verCandSuccess;
data = {'name' : 'val'};
}
else
{
funcSuccess = verElseSuccess;
data = {'name2' : 'val2'};
}
$.ajax({
type: 'POST',
url: wsURL,
data: data,
success: funcSuccess,
error:function ()
{
$("#msg").ajaxError(function()
{
popWaiting(false);
alert(verGenericCallError);
});
},
dataType: 'xml'
});
}
function verCandSuccess(xml){ ... }
function verElseSuccess(xml){ ... }
It's really simple. The only problem I have is the success callback. In case of verElseSuccess I would send a second parameter to that function, more precisely i would handle the idVR (an input parameter of getWSData). How can I accomplish this?

To achieve this, you can do:
...
if(which == 'verCandAll') {
...
}
else {
// create an anonymous function that calls verElseSuccess with a second argument
funcSuccess = function(xml) {
verElseSuccess(xml, idVR);
};
data = {'name2' : 'val2'};
}
...

Use Underscore.js partial function:
funcSuccess = _.partial(verElseSuccess, idVR);

Related

Looping through functions with ajax calls

I'm currently looping through a number of functions that validate particular input values. One in particular requires an ajax call to validate an address. I saw that users here on SO suggested using callbacks to return the value.
The only problem is, by the time it does retrieve the value, the function had already fired within the loop and returned an undefined value. I've been searching around and wasn't sure what the best solution would be. Do I somehow delay the loop? Do I have my function setup right in the first place? Need some serious help.
var validations = [validateUsername, validatePassword, validateAddress];
function submitForm() {
var inputs = validations.map(function(validation) {
return validation();
});
return inputs.every(function(input) {
return input === true;
}); // [true, true, undefined]
}
function validateAddress() {
function addressIsValid(callback) {
$.ajax({
type: 'POST',
url: '/address/validate',
data: $form.serialize(),
dataType: 'json',
success: function(response) {
return callback(response.Data === 200);
}
});
}
function callback(response) {
return response;
}
return addressIsValid(callback);
}
You should use Promises.
First, you should make your asynchronous functions return a Promise:
function validateAddress() {
return new Promise((resolve, reject)=> {
$.ajax({
type: 'POST',
url: '/address/validate',
data: $form.serialize(),
dataType: 'json',
success: response=> {
response.Data === 200 ? resolve() : reject();
}
});
});
}
Then rewrite your submitForm function like this:
function submitForm() {
var promises = validations.map(validation=> validation());
return Promise.all(promises)
}
Then you can use submitForm like this:
submitForm()
.then(()=> {
// form is valid
}, ()=> {
// form is invalid
})

Remake ajax function

Is there a way to make a function that converts default ajax function.
This is the ajax function i have
$.ajax({
type: "POST",
url: "http://" + document.location.host + '/userajax',
data: 'type=register&name=' + name,
beforeSend:function() {
},
success: function(response) {
}
});
This is what i want it to look like
ajax('url', {
method: 'get',
parameters: {
name: $('#name').val()
},
beforeSend: function() {
},
success: function(transport) {
}
});
Ive tried to search on the internet but did not find anything
Sure, you can create the function like this:
function ajax(url, params){
// everything is now available here
console.log( url ); // output: http://www.google.com
// you can get the data of the params object like this
console.log( params.method ); // output: get
// you can execute the beforeSend like this:
params.beforeSend();
// additionally you might want to check everything.
// maybe if the method is NOT set, you want it to always use GET
switch(arguments.length) {
case 1: url = throw new Error('Url should be set');
case 2: params.method = 'get';
case 3: break;
default: throw new Error('illegal argument count')
}
}
You would call this like:
ajax('http://www.google.com', {
method: 'get',
parameters: {
name: $('#name').val()
},
beforeSend: function() {
// some function
},
success: function(transport) {
// some function
}
});
This certainly is possible, it's just a bit of work. Some of the basics you need:
First of all, you need a good understanding of the XMLHTTPRequest API, you can find more info on that on MDN.
Next, finding out how to do a callback, that is actually quite simple, you can pass an anonymous function reference as an option or attribute for a function. That goes like this:
function doSomething(variable, callback){
variable = variable + ' something'; // just doing something with the variable
callback(variable);
}
// then call the function with a callback (anonymous function)
doSomething('doing', function(result){ alert(result); });
You should get an alert that says 'doing something'.
And finally you should know how to read an object, passed as 'options' in the ajax function. Say you have a function like this:
function foo(url, options){
console.log(url);
console.log(options.method);
console.log(options.parameters.name);
}
// call it like this
foo('https://google.com/', {
method: 'get',
parameters: {
name: 'myName'
}
});
That should log the url, method and parameters in the console.
Now from here, you should have all the pieces to put the puzzle together. Good luck!
I don't think so. but you can do this:
$(document).ready(function(){
var parameters = {
name: $("#name").val(),
desc: $("#desc").val()
};
$.ajax({
url: 'path/to/file',
data : parameters,
beforeSend: beforeSubmit,
dataType: "json",
type : 'POST',
})
.done(function(data) {
})
.fail(function() {
console.log("error");
})
})
Also note I don't set the function for the beforeSend directly in the call, I will create an externe function which gives me more freedom.
so I could do this:
function beforeSubmit(){
if(something !== 'somethingelse'){
return false; //ajax call will stop
}else{
return true; //ajax call
}
}

return true or false after ajax post in parent function?

I want to return true or false after making this ajax call:
function write_csv(data, path, file) {
$.ajax({
url: 'functions.php',
type: 'POST',
data: {
operation: 'SAVE_CSV',
save_path: path,
save_file: file,
save_string: data
},
success: function(result) {
console.log('write_file(' + path + file + '); -done');
return true; /* <-- */
}
});
}
Example use case of what I want:
function make_csv () {
/*
|
V
*/
if (write_csv(my_data, my_path, 'export.csv') == true) {
go_on();
}
function go_on() {
alert('YEAH!');
}
}
I know it's async, but maybe someone has another idea.
I won't do it with if's and stuff...
You can use Promises or callbacks to accomplish what you want.
function write_csv(data, path, file, callback) {
$.ajax({
url: 'functions.php',
type: 'POST',
data: {
operation: 'SAVE_CSV',
save_path: path,
save_file: file,
save_string: data
},
success: function(result) {
console.log('write_file(' + path + file + '); -done');
callback(true); /* <-- */
}
});
}
And:
function make_csv () {
/*
|
V
*/
function go_on() {
alert('YEAH!');
}
write_csv(my_data, my_path, 'export.csv', function(result) {
if (result == true) {
go_on();
}
});
}
I am going to go off of jQuery convention and give you a "jQuery" answer since that's what you are using.
In jQuery, you have the ability to pass in a callback (a function to "call" once the actual function you are using finishes) in most jQuery methods. jQuery's convention is to have the callback as the last parameter you pass in into a function. In your example, your write_csv() function would look like this with an extra callback as the last parameter:
function write_csv(data, path, file, callback){
$.ajax({
url: 'functions.php',
type: 'POST',
data: {
operation: 'SAVE_CSV',
save_path: path,
save_file: file,
save_string: data
},
success: function(result) {
console.log('write_file(' + path + file + '); -done');
callback(true);
}
error: function(result){
console.log('async failed');
callback(false);
}
});
}
Notice the error key being passed in and the changes made to the success key in the $.ajax() function.
Now, when you want to use your async function in an if conditional statement, you can use
write_csv(my_data, my_path, 'export.csv', function(response){
if(response === true){
go_on()
}
else if(response === false){
// do something else
}
});

JavaScript Scoping - Passing callback to already defined function

The title is a bit weird, don't quite know the best way to explain it in a sentence...
At present there is an object with 3 functions; func, funcSuccess, and funcFailure. func contains a jQuery ajax request, with this.funcSuccess as the success callback, and funcError as the error callback. func is passed a callback for any success values to be passed back to, however this callback needs to be executed in the funcSuccess code.
Here's the code:
var Obj =
{ func: function (callback) {
$.ajax(
{ type: 'POST'
, url: '/func'
, success: this.funcSuccess
, error: this.funcError
}
)
}
, funcSuccess: function (res) {
// THIS IS WHERE CALLBACK IS NEEDED
callback(res.thing)
}
, funcError: function (res) {
debug(res)
}
}
I'm wondering if there's a tidier way to do it rather than having:
var that = this
$.ajax(
{ type: 'POST'
, url: '/func'
, success: function (res) {
that.funcSuccess(res)
}
, error: this.funcError
}
)
Pretty sure I'm missing something obvious, just not quite with it today...
What about storing the callback explicitly in your object, so you don't have to worry about closure scopes:
var Obj =
{ func: function (callback) {
//this.callback = callback;
$.ajax(
{ type: 'POST'
, url: '/func'
, success: $.proxy(this.funcSuccess, this, callback)
, error: $.proxy(this.funcError, this)
}
)
}
, funcSuccess: function (callback, res) {
callback(res.thing)
}
, funcError: function (res) {
debug(res)
}
}
Edit: I forgot to bind the callbacks to this. In JQuery you can do it with $.proxy, see changes above.
Edit: A further tidy (jQuery 1.6 allows for this) with passing the callback as an argument to $.proxy, so no need to attach it to the current object.
You need to pass the callback into the funcSucess, else it won't have access to it. Here by using a closure:
var Obj = {
func: function (callback) {
return $.ajax({
type: 'POST',
url: '/func',
success: this.makeFuncSuccess(callback),
error: this.funcError
});
}, makeFuncSuccess(callback) {
return function funcSuccess (res) {
callback(res.thing);
};
},
funcError: function (res) {
debug(res)
}
};

jQuery's AJAX call to a javascript class method

I'm a newbee about jQuery's workflow and I would like to setup a javascript class that uses an internal method to make an AJAX request. When the request returns with success, the jQuery AJAX callback should invoke a method owned by the class itself. That's the code:
function IXClock()
{
this.m_intervalID = 0;
this.startClock = function ()
{
this.m_intervalID = setInterval(this.tictac, 500);
}
this.stopClock = function ()
{
clearInterval(this.m_intervalID);
}
this.setClockTime = function(p_strTime)
{
$('#clock').html(p_strTime);
}
this.tictac = function ()
{
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: function (data)
{
this.setClockTime(data);
}
});
}
}
The class represents a clock, with an internal method (tictac) that requests "what's the time" on the server side.
After the server says the time, the jQuery's AJAX method should invoke the setClockTime method of the IXClock class. The invoke method will update the #clock div item in the html page.
The problem is that the method this.setClockTime() results unknown and the javascript return the "this.setClockTime is not a function" error.
The question is: is there a way to invoka a class method from the jQuery's AJAX callback ?
I think that the problem is that the this in your callback function is different from the this referring to IXClock. Try:
var thisClass = this ;
this.tictac = function ()
{
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: function (data)
{
thisClass.setClockTime(data);
}
});
}
Test Case (added to site which already has jQuery loaded):
function uClass () {
this.testFunction = function(input) {
alert(input) ;
}
this.ajaxFunction = function() {
var myClass = this ;
$.ajax({
type: 'POST',
url: '/',
complete: function(data) {
alert(myClass.testFunction) ;
myClass.testFunction(data) ;
this.testFunction(data) ;
}
}) ;
}
}
var k = new uClass() ;
k.ajaxFunction() ;
It happens bacause your callback function leave in global context.
You can choose 2 ways
Use .bind function to bind context to callback function http://www.robertsosinski.com/2009/04/28/binding-scope-in-javascript/
jQuery's AJAX supports transfer some data to callback function. You can write smth like this:
:
this.tictac = function () { $.ajax ({ type: 'POST', context:this, url: '/rap/rapClock.php', complete: function (data) { this.setClockTime(data); } }); }
}
this does not refer to IXClock in your ajax callback. this allways points to the current scope (have a look at this document). You need to do something like this:
this.prototype.tictac = function ()
{
var self = this;
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: function (data)
{
self.setClockTime(data);
}
});
}
You can also use jQuery's .proxy()-function for this purpose:
this.prototype.tictac = function ()
{
$.ajax
({
type: 'POST',
url: '/rap/rapClock.php',
complete: $.proxy(function (data) {
this.setClockTime(data);
}, this)
});
}
The this in the result handler is not what you expect it is. (It is not the IXClock instance)
function IXClock()
{
this.m_intervalID = 0;
}
IXClock.prototype = {
startClock: function ()
{
this.m_intervalID = setInterval(this.tictac, 500);
},
stopClock: function ()
{
clearInterval(this.m_intervalID);
},
setClockTime: function(p_strTime)
{
$('#clock').html(p_strTime);
},
tictac: function ()
{
var that = this;
$.ajax({
type: 'POST',
url: '/rap/rapClock.php',
success: function (data) { // You want success here, not complete, IMO
that.setClockTime(data);
}
});
}
}
If you ask me, that ajax call is doing evil. It does not seem to send any data, nor modify any
state on the server, but is expecting/getting/using data from the php, yet is using the POST method.
Should've been
$.get('/rap/rapClock.php', function (data) {
that.setClockTime(data);
});
One simple solution is, to keep your callback function as self = this. This will support inheritance also.
class Record{
get_data(){
self = this;
$.ajax({
type : "GET",
url : "/get_url",
dataType : "json",
contentType: "application/json; charset=utf-8",
data : {},
success : function(data){
console.log(data);
self.load_table(data);
},
});
}
static load_table(data){
console.log(data);
}

Categories