title: Accessing ioArgs from callback functions
body: <p>I'm upgrading a bunch of old dojo to 1.8. For our ajax request handling we've got a decorator (well, function wrapper) that will perform redirects in certain cases based on the response content, for example:</p>
  
  <pre><code>// Decorator func:
  var redirectDecorator = function(func) {
      var f = function(data, ioArgs) {
          if(data.redirect) {
              // A manual location redirect:
              window.location.href = data.redirect;
          if(data.redirect_xhr) {
              // clone ioArgs, spawn new request to follow redirect etc
              // &lt;snip&gt;
          } else {
              func(response);
          }
      }
      return f;
  }
  
  // Used like so:
  
  dojo.xhrPost({
      url: url
      handleAs: "json",
      form: form,
      load: redirectDecorator(function(data, ioArgs) {
          // do stuff
      })
  });
  </code></pre>
  
  <p>Now, in dojo 1.8 (the <a href="http://dojotoolkit.org/reference-guide/1.8/dojo/request/xhr.html#dojo-request-xhr" rel="nofollow">dojo/request/xhr</a> module) <code>xhr()</code> returns a <code>Deferred</code> for chaining and the callbacks are only supplied the <code>data</code> argument (no <code>ioArgs</code> - apparently these are attached to the promise - see <a href="http://bugs.dojotoolkit.org/ticket/12126" rel="nofollow">http://bugs.dojotoolkit.org/ticket/12126</a>).</p>
  
  <p>In other words, the above ajax call becomes:</p>
  
  <pre><code>xhr.post(url, {
      handleAs: "json",
      form: form
  }).then(function(data) {
      // do stuff
  });
  </code></pre>
  
  <p>Problem is, I can no longer wrap the anonymous function because <code>ioArgs</code> are not supplied. Inspecting the deferred (by breaking the chaining) doesn't appear to work either and would require more re-engineering than I'd like.</p>
  
  <p>Any ideas?</p>
  
  <hr>
  
  <p>Thanks Ken (for your help at #dojo too). To elaborate, the solution is to use <code>dojo/request</code> and use the <code>.response</code> deferred promise instead, which provides the necessary info:</p>
  
  <pre><code>// Decorator func:
  var redirectDecorator = function(func) {
      var f = function(response) {
          var data = response.data;
          if(data.redirect) {
              // A manual location redirect:
              window.location.href = data.redirect;
          if(data.redirect_xhr) {
              request(data.redirect_xhr, response.options).then(func);
          } // more conditions follow.
      }
      return f;
  }
  
  request.post(url, {
      handleAs: "json",
      form: form
  }).response.then(redirectDecorator(function(response) { // &lt;-- note .response.then(
      // do stuff where data is response.data
  }));
  </code></pre>