#11558 closed bug (invalid)
Invoking $.data("name", undefined) does not remove data as documented
Reported by: | dcitron | Owned by: | Rick Waldron |
---|---|---|---|
Priority: | high | Milestone: | 1.next |
Component: | data | Version: | 1.7.2 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
The documentation for removeData says:
When using
.removeData("name")
, jQuery will attempt to locate adata-
attribute on the element if no property by that name is in the internal data cache. To avoid a re-query of thedata-
attribute, set the name to a value of eithernull
orundefined
(e.g..data("name", undefined)
) rather than using.removeData()
.
However, "$data("name", undefined)
" does not actually remove the stored data as documented.
In 1.7.1, passing undefined
as the second argument would break the chain, which was fixed via #5571.
In 1.7.2 and edge, the chain is no longer broken, but the data is still not removed: http://jsfiddle.net/AvqeW/2/
Change History (12)
comment:1 Changed 11 years ago by
Component: | unfiled → data |
---|---|
Milestone: | None → 1.next |
Owner: | set to Rick Waldron |
Priority: | undecided → high |
Status: | new → assigned |
comment:2 Changed 11 years ago by
So there is a case where a setter should actually do something with undefined
.
@rwaldron, this was in the back of my mind for the jQuery.access
rewrite. Unless you've already gone down another path, I recommending adding another parameter forceSet
either before or after pass
, to be used disjunctively alongside value !== undefined
. With that in place, the call to it in .data
would need only minor tweaking:
fn
: trigger getter behavior onarguments.length === 0
instead ofvalue === undefined
forceSet
:arguments.length > 1
comment:3 Changed 11 years ago by
Do we really need to generalize this case, or can it just be handled in jQuery.data()
as a special case?
comment:4 Changed 11 years ago by
We essentially are special-casing .data
, but looking at that block of setter code makes me suspect that generalization is the most efficient way to do it:
parts[1] = value; this.each(function() { var self = jQuery( this ); self.triggerHandler( "setData" + part, parts ); jQuery.data( this, key, value ); self.triggerHandler( "changeData" + part, parts ); });
comment:5 Changed 11 years ago by
Keywords: | needsdocs added |
---|---|
Resolution: | → invalid |
Status: | assigned → closed |
This is actually not a bug, the docs need to be updated to show that only "null" should be used.
Take a look at historic versions of jQuery supporting the behaviour:
- 1.2.6: http://jsfiddle.net/rwaldron/AvqeW/13/
- 1.3.2: http://jsfiddle.net/rwaldron/AvqeW/12/
- 1.4.4: http://jsfiddle.net/rwaldron/AvqeW/11/
- 1.5.2: http://jsfiddle.net/rwaldron/AvqeW/8/
- 1.6.4: http://jsfiddle.net/rwaldron/AvqeW/9/
- 1.7.1: http://jsfiddle.net/rwaldron/AvqeW/10/
needsdocs, update to:
To avoid a re-query of the data- attribute, set the name to a value of null (e.g. .data("name", null)) rather than using .removeData().
comment:6 Changed 11 years ago by
To be clear, this documentation-only change means that the only way to remove the data item (i.e. to make it so that a future invocation of .data("name")
returns undefined
) is to use .removeData("name")
and suffer the possible re-query of the data-
attribute.
comment:8 Changed 11 years ago by
But using "null" doesn't remove it ... that just sets it to "null", so comparison against undefined
will not work, resulting in an arguably asymmetrical situation (a given data item is undefined
when the page first loads but may be null
later and mean the same thing).
It's fine--just a point worth making, I though.
comment:9 Changed 11 years ago by
Please understand that "undefined" never worked the way you're expecting it to, in fact, jQuery actually has tests that confirm "undefined" never unsets a data property. The properties have actually never been "removed"
comment:10 Changed 11 years ago by
Right--that's fine. What's confusing is if the documentation implies that .data("name", null)
will have the same effect as .removeData("name")
. It will not:
.data("name", null)
will set the value tonull
(future calls to.data("name")
will yieldnull
).removeData("name")
will remove the data item entirely
(future calls to.data("name")
will yieldundefined
)
comment:11 Changed 11 years ago by
Ok, thanks for the added clarification - that will be helpful when the docs are updated
comment:12 Changed 10 years ago by
Keywords: | needsdocs removed |
---|
Confirmed. Patch or otherwise to follow