Alan Whitelaw
Alan Whitelaw

Reputation: 16880

Is there a better way to overwrite a JS ajax callback?

I needed to perform a differnt action when an ajax call was completed depending on which event handeler was fired.

Here is what I have come up with:

  // create object to manipulate later
  save = {
    save_to_db: function () {
      $.ajax({
        ...snip...
        success: function (result) {
          save.callback();
        }
      })
    },
    callback: function () {
      console.log('default callback');
    }
  };

  // normal useage
  $('#b_save').click(function (e) {
    save.save_to_db()
  });

  // one off special useage
  $('#b_add_to_basket').click(function (e) {
    e.preventDefault();
    save.old_callback = save.callback();
    save.callback = function () {
      console.log('overridden call back baby!!')
    }
    save.save_to_db();
    save.callback = save.old_callback();
  });

This question: Javascript callback functions with ajax passes in the callback function, maybe I am missing how to have a default callback that can be overwritten.

My question is, is there a better way to acomplish this, and can it be optimised at all?

Upvotes: 2

Views: 311

Answers (2)

hugomg
hugomg

Reputation: 69934

From a stylistic perspective, You could use a function-maker function:

function make_saver_function(success_callback){
    return function () {
      return $.ajax({
        ...snip...
        success: sucess_callback
      });
    };
}

This would allow you to easily create custumized save functions:

save_to_db = make_saver_function(function(){
    console.log('default callback');
});

one_off_save_to_db = make_saver_function(function () {
      console.log('overridden call back baby!!')
});

Upvotes: 4

Alnitak
Alnitak

Reputation: 339816

It would be better not to pass the callback in the $.ajax call at all - this would be a good use for jQuery 1.5's Deferred objects.

Change your save_do_db() so that it returns the result of the $.ajax call, and remove the success: field:

save_to_db: function () {
  return $.ajax({
    ...snip...
    }
  })
},
callback: ...,
overridden: ...,

Then register your success callbacks when the AJAX call is invoked:

// normal usage
$('#b_save').click(function (e) {
  save.save_to_db().then(save.callback);
});

// one off special usage
$('#b_add_to_basket').click(function (e) {
    e.preventDefault();
    save.save_to_db().then(save.overridden);
});

Note that you may need to do some extra work to ensure that this contains a sane value within the callback functions.

Upvotes: 4

Related Questions