I have this interesting jQuery function. It basically adds a click handler to link, and when that is clicked, it will load a form to allow the user to edit the content. and the form is submitted by AJAX, and will display a success message when it's done.
The outline is below; needless to say, this is messy. I could have each of the callback as a class method. What other ways are there to refactor nested functions? I am also interested to see if there are ways that variables declare in a parent function still retain its value down to the nested function after refactoring
$('a.edit').click( function() {
// ..snipped..
// get form
$.ajax({
success: function() {
// add form
// submit handler for form
$(new_form).submit(function() {
// submit via ajax
$.ajax({
success: function(data) {
// display message
}
})
})
}}
)
}
I guess the interesting part of your question is how to refactor without loosing access to the closure variables. Here is my suggestion:
Version one: nested, with closures and variable access:
var a;
$('a.edit').click( function() {
var b;
$.ajax({
success: function() {
var c;
$(new_form).submit(function() {
var d;
$.ajax({
success: function(data) {
// a,b,c,d are all visible here.
// note that a references the same object for all calls of the success function, whereas d is a different variable for each call of submit.
// this behaviour is called closure: the 'enclosed' function has access to the outer var
}
})
})
}
})
})
Version two: less nested, but without closures and without variable access:
var a;
$('a.edit').click(onEdit);
var onEdit = function() {
var b;
$.ajax({success: onEditSuccess});
};
var onEditSuccess = function() {
var c;
$(new_form).submit(onSubmit);
};
var onSubmit = function() {
var d;
$.ajax({success: onSubmitSuccess});
}
var onSubmitSuccess = function(data) {
// a is visible (global var)
// b,c,d NOT visible here.
};
Version three: less nested and with unnamed functions and parameters to get access to the closure variables:
var a;
$('a.edit').click(function(){onEdit(a)});
var onEdit = function(a) {
var b;
$.ajax({success: function(){onEditSuccess(a,b)}});
};
var onEditSuccess = function(a,b) {
var c;
$(new_form).submit(function(){onSubmit(a,b,c)});
};
var onSubmit = function(a,b,c) {
var d;
$.ajax({success: function(data){onSubmitSuccess(data,a,b,c,d)}});
}
var onSubmitSuccess = function(data,a,b,c,d) {
// a,b,c,d are visible again
// nice side effect: people not familiar with closures see that the vars are available as they are function parameters
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With