Reputation: 35349
I created a reusable ajax pattern in jQuery. It works well, but it's starting to become messy as I add more actions to it.
Look at the success
callback. Every time I add a new action, the conditional logic gets messier: if actionType == foo, then bar
etc...
$('.action-panel').delegate('a', 'click', function () {
var link = $(this),
actionTypeId = link.data('action-type-id'),
// Do stuff, like getting the url from the link, etc...
// Throttle multiple clicks
$.ajax({ //[snip]
beforeSend: function () {
link.toggleClass('on');
},
error: function () {
link.toggleClass('on');
},
success: function (response) {
if (response.success) {
if (actionTypeId === 4) {
// do stuff for action 4
}
else if (actionTypeId === 2) {
// do stuff related to action 2
}
else if (actionTypeId === 3) {
// do stuff related to action 3
}
// More action types, etc...
}
else {
link.toggleClass('on');
}
// decide to show tooltip or not
});
// do some extra stuff like re-enable the link (throtled earlier)
I should factor out the ajax function by itself. But I can't figure out a way to separate the callback conditionals into their own blocks/functions, and pass back the result.
Any ideas? Please bare in mind I'm new to JavaScript and jQuery.
Upvotes: 1
Views: 127
Reputation: 34168
I like to use a switch for this.
switch (actionTypeId) {
case 4:
$('.fav-count').text(response.newcount);
$('.fav-count').toggleClass('on');
break;
case 2:
link.siblings('.liked').removeClass('on');
link.siblings('.count').text(response.newcount);
break;
case 3:
link.siblings('.disliked').removeClass('on');
link.siblings('.count').text(response.newcount);
break;
default:
break;
}
Note that the first item found true will be executed as long as you have a break in there.
Alternate way: Note the response.success and the NEED for breaks then.
switch (true) {
case !response.success:
link.toggleClass('on');
break;
case actionTypeId===4:
$('.fav-count').text(response.newcount);
$('.fav-count').toggleClass('on');
break;
case actionTypeId===2:
link.siblings('.liked').removeClass('on');
link.siblings('.count').text(response.newcount);
break;
case actionTypeId===3:
link.siblings('.disliked').removeClass('on');
link.siblings('.count').text(response.newcount);
break;
default:
break;
}
Upvotes: 1
Reputation: 47099
Maybe you could put all the callbacks in a seperate Object:
var success_callbacks = {};
success_callbacks["2"] = function(response) {
link.siblings('.liked').removeClass('on');
link.siblings('.count').text(response.newcount);
};
success_callbacks["3"] = function(response) {
link.siblings('.disliked').removeClass('on');
link.siblings('.count').text(response.newcount);
};
success_callbacks["4"] = function(response) {
$('.fav-count').text(response.newcount);
$('.fav-count').toggleClass('on');
};
And then call them in your success handler
$('.action-panel').delegate('a', 'click', function () {
var link = $(this),
actionTypeId = link.data('action-type-id'),
// Do stuff, like getting the url from the link, etc...
// Throttle multiple clicks
// BEGIN AJAX
$.ajax({
context: this,
dataType: 'json',
url: url,
beforeSend: function () {
link.toggleClass('on');
},
error: function () {
link.toggleClass('on');
},
success: function (response) {
if (response.success) {
success_callbacks[action-type-id](response);
}
else {
link.toggleClass('on');
}
// decide to show tooltip or not
});
// do some extra stuff like re-enable the link (throtled earlier)
Upvotes: 1
Reputation: 105220
Have an "action" map like this, saving the action ID and the function
to execute:
var actions = {
'4' : function () {
$('.fav-count').text(response.newcount);
$('.fav-count').toggleClass('on');
},
'2' : function() {
link.siblings('.liked').removeClass('on');
link.siblings('.count').text(response.newcount);
}
}
Then on the success
callback you just do:
if (response.success) {
actions[actionTypeId]();
}
Note you'll probably have to change a bit things since link
wont be visible from the callback but you can do something like actions[actionTypeId](this);
and then have the callbacks receive the link as a parameter.
Upvotes: 5