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)
}
};
Related
So this function getXmlData() get's called across the app who's main responsibility is to return xml to and save it to a variable, in this example below it is 'test'
var test = getXmlData();
function getXmlData() {
queryData(getData);
}
function getData(xml) {
if (xml) {
return xml;
}
}
function queryData(callback){
$.ajax({
url: "/echo/JSON",
type: 'POST',
success: function(xml){
callback(xml);
},
error: function(){
console.log("Error!!");
}
})
}
Now we know that here parent function will return before the callback is executed and so 'test' variable will be undefined.
I'm not sure how can I handle this situation here. I'm tied to using this structure. I basically want getXmlData to return xml that is being returned in queryData. Suggestions!?
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
}
}
If I have to leverage niceties of jQuery AJAX API and set my own custom settings for each ajax call my app makes like below:
Say I have a page which displays employee information within table by making ajax calls to some API.
define(["jQuery"], function($) {
var infoTable = function (options) {
function init() {
// Provide success callback
options.success_callback = "renderData";
getData();
}
function renderData() {
// This callback function won't be called as it is not
// in global scope and instead $.ajax will try to look
// for function named 'renderData' in global scope.
// How do I pass callbacks defined within requirejs define blocks?
}
function getData() {
$.ajax({
url: options.apiURL,
dataType: options.format,
data: {
format: options.format,
APIKey: options.APIKey,
source: options.source,
sourceData: options.sourceData,
count: options.count,
authMode: options.authMode
},
method: options.method,
jsonpCallback: options.jsonpCallback,
success: options.success_callback,
error: options.error_callback,
timeout: options.timeout
});
}
}
return {
init: init
}
}
How do I achieve this?
I know we can use JSONP request as require calls but that restricts me to using jsonp, making GET requests and all other features $.ajax offers.
This example would let you either use a default success callback, or provide an override, using:
success: options.successCallback || renderData
(The example uses jsfiddle rest URLs - this fact is unimportant, and stripped out the data object to keep the example short)
define("mymodule", ["jquery"], function($) {
function renderData() {
console.log("inside callback");
}
function getData(options) {
$.ajax({
url: options.apiURL,
dataType: options.format,
method: options.method,
jsonpCallback: options.jsonpCallback,
success: options.successCallback || renderData,
error: null,
timeout: options.timeout
});
}
return {
getData: getData
}
});
require(["mymodule"], function(m) {
console.log(m, m.getData({
apiURL: "/echo/json/"
}));
console.log(m, m.getData({
successCallback: function() { console.log("outside callback"); },
apiURL: "/echo/json/"
}));
});
Would print:
GET http://fiddle.jshell.net/echo/json/ 200 OK 263ms
Object { getData=getData()} undefined
GET http://fiddle.jshell.net/echo/json/ 200 OK 160ms
Object { getData=getData()} undefined
inside callback
outside callback
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);
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);
}