#5853 closed bug (duplicate)
Ajax callback context is not original object.
Reported by: | borgar | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | 1.4.1 |
Component: | ajax | Version: | 1.4 |
Keywords: | ajax callback context | Cc: | |
Blocked by: | Blocking: |
Description
Callbacks pass a different object as a context than the one originally assigned, if the original object is a literal object.
var ctx = {}; $.ajax({ context: ctx, success: function () { console.log( this === ctx ); // false } });
My understanding is that this happens because $.extend is now cloning literal objects rather than copying the reference. Settings are passed through $.extend and the context is read from them, rather than original settings. Thus all literal objects passed in as a context will be replaced by a fresh identical objects. Preventing any assignments to them.
The fix should be simple:
ajax: function( origSettings ) { var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings); var jsonp, status, data, callbackContext = s.context || s, // ...
This should be something like:
ajax: function( origSettings ) { var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings); var jsonp, status, data, callbackContext = (origSettings && origSettings.context) || s, // ...
Change History (5)
comment:1 Changed 13 years ago by
Resolution: | → duplicate |
---|---|
Status: | new → closed |
comment:2 Changed 13 years ago by
Resolution: | duplicate |
---|---|
Status: | closed → reopened |
This is absolutely not a duplicate of #5838.
This is a separate issue that happens when a literal object or array IS SET as the context property: The callback context is a fresh object that looks the same, feels the same, but is not the same. For all other object types the same object is passed through:
var ctx = function(){}; $.ajax({ context: ctx, success: function () { console.log( this === ctx ); // true } });
See additional (potential) problems in forum post: http://forum.jquery.com/topic/ajax-contexts
Here is a slightly more complex, but closer to real-world scenario which illustrates how this is failing for me:
(function(){ var private = { cache: null, loaddata: function () { if ( !this.cache ) { console.log( 'no cache present' ); $.ajax({ async: false, // ignore this, it's for the demo to work context: this, success: function ( r ) { this.cache = r; // where does r go? } }); } } }; $.loader = function () { private.loaddata(); }; })(); $.loader(); $.loader(); // keeps loading because cache is empty $.loader(); // ... and so on
Not only is the private
object inaccessible within the success callback but effort is also wasted on cloning the object (and it's empty cache member) every call to $.ajax
.
I guess the programmer can still use closures, we've been doing fine with them until now. My problem with this is that it SEEMS to work, but doesn't.
comment:3 Changed 13 years ago by
This is a duplicate of #5924, or rather it of this. Fixed in 1.4.1.
comment:4 Changed 12 years ago by
Keywords: | ajax callback context added |
---|---|
Resolution: | → duplicate |
Status: | reopened → closed |
This is a duplicate of #5924 which had a fix made for it in 1.4.1. Closing.
Duplicate of #5838.