pass argument to jQuery .on() event handler callback In my web application, a user will click a button which will call a function that triggers an AJAX call.  That function accepts a single argument.  I would like to be able to put that function in place of the anonymous function in the jQuery event handler.  I suspect that this is a scoping issue...

Here is my working code:

(function () {
 'use strict';

  var postId;

  function userAddFlagToPost (userId) {
    return $.ajax({
      type: 'POST',
      timeout: 1000 * 3;,
      url: '/someApi/postId',
      data: {
        userId: userId
      },
    }).done(onFlagSubmitDone)
      .fail(onFlagSubmitDone);
  }

  function onLoggedIn() {
    var userId = getCookie('some_user_auth') || null;

    $(SELECTORS.POST_FLAG).on('click', function() {
      postId = $(this).data('postId');
    });

    $(SELECTORS.SUBMIT_BUTTON).on('click', function() {
      userAddFlagToPost(userId);
    });
  }

  function init() {
    eventQ.register(onLoggedIn);
  }

  init();
})();


I would like to be able to do:

$(SELECTORS.SUBMIT_BUTTON).on('click', userAddFlagToPost(userId));


I'd appreciate any info or advice on how to go about refactoring this code, thanks!
It seems that what you want is a partially-applied function. One way this can be achieved is using Function.prototype.bind().:

$(SELECTORS.SUBMIT_BUTTON).on('click', userAddFlagToPost.bind(null, userId));


Pass null as the first argument unless the context needs to be set (e.g. to this for the same context?) and then userId as the second argument will pass that as the first argument to the function. Then note that userAddFlagToPost() would then receive the event Event eventobject argument per the `.on() method.

With this approach, the function is not invoked (as it would be with your proposed syntax) but instead the partially applied function is invoked when the click handler is applied.

See this demonstrated in the snippet below:



(function() {
  'use strict';

  var postId;
  var SELECTORS = {
    SUBMIT_BUTTON: '#submitButton',
    DISPLAY_ELEMENT: '#displayElement'
  };

  function userAddFlagToPost(userId) {
    var text = 'userId passed to userAddFlagToPost: ' + userId + ' count of arguments: ' + arguments.length;
    Array.from(arguments).forEach(function(argument, index) {
      text += '&lt;br&gt; typeof arg[' + index + ']: ' + (typeof argument);
    });
    $(SELECTORS.DISPLAY_ELEMENT).html(text);
  }

  function init() {
    var userId = 1337; //hard code for now
    $(SELECTORS.SUBMIT_BUTTON).on('click', userAddFlagToPost.bind(null, userId));
  }
  init();
})();
#displayElement {
  border: 1px solid #0f0;
  margin: 4px;
  padding: 10px;
}
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"&gt;&lt;/script&gt;
&lt;button id="submitButton"&gt;Click this to see the partially function called&lt;/button&gt;
&lt;div id="displayElement"&gt;&lt;/div&gt;




Note that there is a jQuery shortcut method .click() that could be used in place of .on('click'):

$(SELECTORS.SUBMIT_BUTTON).click(userAddFlagToPost.bind(null, userId));