Reputation: 549
I'm attempting to write a couple of functions using jQuery to help me test some api endpoints that I'm writing in php. I'm a novice when it comes to Javascript and jQuery and I'm having difficulty working out what I need to read up on in order to get things working that way I need it.
Here are the requirements I'm attempting to meet:
success
and in orderdata
variable return by success: function(data)
from within the api()
functionI've read the jQuery docs and believe that deferred
and promises
are possibly the avenue I should be pursuing but I am not able to get an example working.
Simplified versions of my two functions:
(For clarity)
// Returns data from an api request providing something hasn't gone horribly wrong
function api( api, method, endpoint, query ) {
$.ajax({
type: method,
url: '/api/' + api + '/' + endpoint,
data: query,
dataType: 'json',
success: function(data) {
// I currently have a single hardcoded function
populate( data.result, '#resource', null );
},
error: function( data ) {
// Debug
dump(data.result);
}
});
// Do some other stuff here
}
// Example call
$('body').on('click', '#bigFatButton', function() {
// I would like to specify a function (or chain of functions)
// to be fired on success along with the api() function
api('resources', 'get', 'document', {
debug: '1',
id: '7'
})
});
This is what I'd like to achieve (something nice, short and reusable):
fn1()
and fn2()
are fired in order and can both access the data returned by api()
api('resources', 'get', 'document', {
debug: '1',
id: '7'
}).fn1(data, 'custom', 'params').fn2(data, {other: 'params'}).alert('wooty!');
What would be the best way of achieving something similar to this? A nudge in the right direction would be very much appreciated!
Thank you.
Upvotes: 0
Views: 122
Reputation: 966
1 - I would use the methods as arguments in an anonymous function
api('resources', 'get', 'document', {
debug : true, // better to say true or false :)
id : 7, // if your id is a number use number
callback : function(data){
fn1(data);
fn2(data);
}
});
2 - Using an array, could be cool if you have a lot to run.
// in api method..
for(var i; i < cbks.lengths; i++){
cbks[i](); // execute one by one the callbacks declared.
}
api('resources', 'get', 'document', {
debug : true, // better to say true or false :)
id : 7, // if your id is a number use number
[fn1, fn2, fn3] // here are the callbacks
});
Upvotes: 0
Reputation: 1
Try adding return
statement before $.ajax()
, returning data
from api
, utilizing .then()
function api( api, method, endpoint, query ) {
// return `$.ajax()` jQuery promise to `.then()`
return $.ajax({
type: method,
url: '/api/' + api + '/' + endpoint,
data: query,
dataType: 'json',
success: function(data) {
// I currently have a single hardcoded function
populate( data.result, '#resource', null );
// return `data`
return data
},
error: function( data ) {
// Debug
dump(data.result);
}
});
// Do some other stuff here
}
// Example call
$('body').on('click', '#bigFatButton', function() {
// I would like to specify a function (or chain of functions)
// to be fired on success along with the api() function
api('resources', 'get', 'document', {
debug: '1',
id: '7'
}).then(function(data) {
$.when(fn1(data, 'custom', 'params')
, fn2(data, {other: 'params'})
.then(function() {alert('wooty!')})
})
});
Upvotes: 2
Reputation: 13304
Due to the asynchronous nature of AJAX you can't chain functions directly from the API function. The data would simply not be available when the chained functions are ran. However you can do it inside the success function. You will need to construct a wrapper function.
function wrapper()
{
return {
fn1 : function(data){
//execute code for fn1 here
return wrapper();
},
fn2 : function(data){
//execute code for fn2 here
return wrapper();
},
alert : window.alert.bind(window);
}
}
}
By running wrapper.fn1(data, arguments).fn2(data, arguments).alert("whoot!")
inside the success function it will work the way you intended.
Everytime you call upon the wrapper
function, or a function inside it it will return the full object allowing for function chaining.
A more efficient design would be to construct the functions outside the wrapper object and only reference them inside the wrapper function.
Upvotes: 0