Pass extra parameters to jquery ajax promise callback

16,132

I've discovered that it's really easy including a new indirection level, just like this:

var extraParam = 'xyz';

$.post("MyUrl", JSON.stringify(data))
        .done(function(a,b,c) { onMyUrlLoaded(a, b, c, extraParam); });

In this way, the callback will receive the extraParam, besides the three standard parameters.

Of course, this can also be done if the promise is stored in a variable, for example one returned by a function, like this:

function getUrl() {
  // some code ...
  var promise = $.post("MyUrl", JSON.stringify(data));
  return promise;
}

This can be invoked and used like this:

var promise = getUrl();
var extraParam = 'xyz';
promise.done(function(a,b,c) { onMyUrlLoaded(a, b, c, extraParam); });

There is a shorter syntax for doing this, which consist in using bind.

When you call bind in a function, you get a new function. The first parameter passed to bind will become this inside the body of the return function. The additional parameters will be prepended to the original arguments.

The following code shows how to use bind. For TL;DR look the two last blocks of code

// To show the results in the page
var $log = $('#log');
var log = function(text) {
    $log.append(text+'<br/>');
};

// This returns a promise, and resolves it after the specified
// timeout. This behaves like a jQuery ajax call (but for the
// provided timeout)
var trigger = function(timeout) {
    log('<b>trigger</b> invoked');
    var deferred = $.Deferred();
    setTimeout(function() {
        log('<b>trigger</b> resolving promise');
        deferred.resolve('A','B');
    }, timeout);
    return deferred;
};

// This is the function we want to invoke
// The promise returns a and b - the extra params
// must be supplied in some way
var extraParams = function(extra1, extra2, a, b) {
    log('<b>extraParams</b> extra1:' + extra1);
    log('<b>extraParams</b> extra2:' + extra2);
    log('<b>extraParams</b> a:' + a);
    log('<b>extraParams</b> b:' + b);
};


// Doing it using indirection
trigger(500).then(function(a,b) {
  extraParams('extra1','extra2',a,b);
});

// Doing it using bind()
trigger(1200).then(
  extraParams.bind(this,'extra1','extra2')
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="log">
</div>
Share:
16,132

Related videos on Youtube

JotaBe
Author by

JotaBe

After years in front of a computer... After millions of keystrokes... After thousands of compilations... I must have done something right!

Updated on June 20, 2022

Comments

  • JotaBe
    JotaBe almost 2 years

    I need to pass an extra parameter to the .done promise callback of a jquery ajax call:

    $.post("MyUrl", JSON.stringify(data))
            .done(onMyUrlLoaded);
    

    The standard callback, would be like this:

    function onMyUrlLoaded(data, textStatus, jqXHR) { /* function code */ };
    

    But I need to pass an extra parameter to my callback, like this:

    function onMyUrlLoaded(data, textStatus, jqXHR, extraParam) { /* code */ };
    

    How can I do it?

    NOTE: this question is not a duplicate, because it's specifically about promise callbacks. Besides this question is two years older than the one which is said to duplicate, and gives a much more thorough answer, and an specifica answer regarding promises.

  • bart
    bart over 5 years
    Thanks for answering your own question!
  • drake7
    drake7 almost 4 years
    Excellent! Exactly what I was looking for. I omitted b and c: var extraParam = "Casablanca"; $.get( "./movies.xml" ).done(function(data) { findMovie(data, extraParam); }); function findMovie(data, extraParam) { var year = $(data).find("MOVIE").has("NAME:contains('" + extraParam + "')").find("YEAR").text(); console.log(extraParam + " is a movie from " + year + ".") }