75

JavaScript code I'm starting with:

function doSomething(url) {  
   $.ajax({
      type: "GET",  
      url: url,  
      dataType: "xml",  
      success: rssToTarget  
   });  
}    

Pattern I would like to use:

//where elem is the target that should receive new items via DOM (appendChild)
function doSomething(url, elem) {
   $.ajax({
      type: "GET",
      url: url,
      dataType: "xml",
      success: rssToTarget(elem)
   });
}  

I don't think I can get the callback to work this way, right? What is the proper pattern? I don't want to use global variables necessarily to temporarily hold the elem or elem name.

Caleb Eby
  • 356
  • 3
  • 14
BuddyJoe
  • 69,735
  • 114
  • 291
  • 466
  • http://stackoverflow.com/questions/2602981/jquery-how-to-pass-additional-parameters-to-success-callback-for-ajax-call use invokedata – Roman Rhrn Nesterov Mar 27 '12 at 06:10
  • For future reference: You need to store the callback function (`rssToTarget`) within the `success` property of the object literal you are passing to `$.ajax()`, so jQuery can call that function once the AJAX request is completed. By adding `(elem)` to the end of the function name, you are mistakenly invoking `rssToTarget` and storing its return value within `success`. In JS, adding parentheses at the end of a function name will invoke it. – BrunoF Feb 24 '17 at 18:00

3 Answers3

97

Like this...

function doSomething(url, elem) {
  $.ajax({
     type: "GET",
     url: url,
     dataType: "xml",
     success: function(xml) {
       rssToTarget(xml, elem);
     }
  });
}

Answer to your comment: Does use of anonymous functions affect performance?

Community
  • 1
  • 1
Josh Stodola
  • 81,538
  • 47
  • 180
  • 227
  • 3
    aha +1. Do you pay any performance price for creating anon functions everywhere? – BuddyJoe Jul 28 '09 at 13:42
  • 2
    And I guess it would really be.... success: function(xml) { rssToTarget(xml, elem); } – BuddyJoe Jul 28 '09 at 13:43
  • if you wrap your `$.ajax` call in a loop, this approach will create new function (`function(xml) { ... }`) for every loop, consuming more memory. – stack247 Aug 19 '15 at 21:57
30

The pattern you'd like to use could work if you create a closure inside your rssToTarget function:

function rssToTarget(element) {
  return function (xmlData) {
    // work with element and the data returned from the server
  }
}

function doSomething(url, elem) {
    $.ajax({ type: "GET",
         url: url,
         dataType: "xml",
         success: rssToTarget(elem)
       });
}

When rssToTarget(elem) is executed, the element parameter is stored in the closure, and the callback function is returned, waiting to be executed.

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
0

What about exploting Ajax request settings context?

function doSomething(url, elem) {
   $.ajax({
      type: "GET",
      url: url,
      dataType: "xml",
      success: rssToTarget,
      elem: elem               // <- add as settings argument
   });
}

rssToTarget(ans) {
    elem = this.elem;          // <- get it back using "this"
}

By default callback context is a merge of $.ajaxSettings and settings passed to $.ajax. So if you add your fields in $.ajax settings they go into callback context. That is, you can retrieve them from context using this.

Niki Romagnoli
  • 1,406
  • 1
  • 21
  • 26