1

I'm migrating to jQuery 1.8 and changing my ajax result handlers from success: and error: to done() and fail(). However, inside my done() handlers I start getting errors like

this.each is not a function

although the ajax call contains the context: parameter as before. Somehow the this context has vanished.

This is the calling code:

function vzload(args) {
    return $.ajax(args).then(function(json) {
        if (json.exception) {
            var e = new Exception(json.exception.type, args.url + ':<br/><br/>' + json.exception.message);
            vz.wui.dialogs.exception(e);
            return $.Deferred().reject();
        }
        return $.Deferred().resolve(json);
    });
}

And this is when the error occurs:

var deferred = vz.load({
    controller: 'capabilities',
    context: someobject
}).done(function(json) {
    this.each(...)
});

I've tried changing the resolution to:

return $.Deferred().resolveWith(this, json);

and now the error is

TypeError: json is undefined

What is the correct way to modify the ajax result Deferred when using context objects?

andig
  • 13,378
  • 13
  • 61
  • 98
  • 1
    `I'm migrating to jQuery 1.8 and changing my ajax result handlers from success: and error: to done() and fail()` You don't *need* to do this - `success` and `error` are still perfectly valid. Also, if you're upgrading jQuery, why not go to the latest on the 1.x branch? – Rory McCrossan Dec 23 '15 at 17:16
  • @Rory I needed a way to modify a success result to a failure based on the json response content- Deferreds seemed the 'right' (and only?) way to achieve this. – andig Dec 23 '15 at 17:40
  • Just have the functionality which handles errors extracted out to it's own function so you can call it from `error` and `success` if a condition is hit. – Rory McCrossan Dec 23 '15 at 18:22
  • @andig: Despite what Rory says, you're right – Bergi Dec 23 '15 at 20:07
  • 1
    Why do you need to use `this` in the callback at all? Why not just just call `someobject.each` directly? Seems the best way to go ([but there are alternatives if you want](http://stackoverflow.com/q/20279484/1048572)) – Bergi Dec 23 '15 at 20:08
  • @Bergi very good point. I do actually need it when calling vz.load from prototype functions. Also, if I didn't know which clients consumed my vz.load function it would probably best practice to to preserve this when fiddeling with the Deferred. – andig Dec 28 '15 at 15:58

1 Answers1

0

Oh dear. Seems I've made the same mistake in both cases. According to https://api.jquery.com/deferred.resolveWith/ the function expects args as an array, not a single plain argument. Only in the first case this mistake was covered by failing even before hitting json not being defined.

So the "right" way seems to be:

return $.Deferred().resolveWith(this, [json]);
andig
  • 13,378
  • 13
  • 61
  • 98