Skip to main content

Bug Tracker

Side navigation

#11558 closed bug (invalid)

Opened April 05, 2012 04:51AM UTC

Closed April 07, 2012 11:15PM UTC

Last modified October 15, 2012 09:59PM UTC

Invoking $.data("name", undefined) does not remove data as documented

Reported by: dcitron Owned by: rwaldron
Priority: high Milestone:
Component: data Version: 1.7.2
Keywords: Cc:
Blocked by: Blocking:

The documentation for removeData says:

When using .removeData("name"), jQuery will attempt to locate a data- attribute on the element if no property by that name is in the internal data cache. To avoid a re-query of the data- attribute, set the name to a value of either null or undefined (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:

Attachments (0)
Change History (12)

Changed April 05, 2012 05:19AM UTC by rwaldron comment:1

component: unfileddata
owner: → rwaldron
priority: undecidedhigh
status: newassigned

Confirmed. Patch or otherwise to follow

Changed April 05, 2012 02:18PM UTC by gibson042 comment:2

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 on arguments.length === 0 instead of value === undefined
  • forceSet: arguments.length > 1

Changed April 06, 2012 03:36AM UTC by dmethvin comment:3

Do we really need to generalize this case, or can it just be handled in as a special case?

Changed April 06, 2012 01:16PM UTC by gibson042 comment:4

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 ); this, key, value );
	self.triggerHandler( "changeData" + part, parts );

Changed April 07, 2012 11:15PM UTC by rwaldron comment:5

keywords: → needsdocs
resolution: → invalid
status: assignedclosed

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:

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().

Changed April 10, 2012 02:28AM UTC by dcitron comment:6

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.

Changed April 10, 2012 04:38AM UTC by rwaldron comment:7

No, use "null"

Changed April 11, 2012 02:26AM UTC by dcitron comment:8

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.

Changed April 11, 2012 04:14AM UTC by rwaldron comment:9

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"

Changed April 11, 2012 06:07AM UTC by dcitron comment:10

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 to null\\\\(future calls to .data("name") will yield null)
  • .removeData("name") will remove the data item entirely\\\\(future calls to .data("name") will yield undefined)

Changed April 11, 2012 12:46PM UTC by rwaldron comment:11

Ok, thanks for the added clarification - that will be helpful when the docs are updated

Changed October 15, 2012 09:59PM UTC by mikesherov comment:12

keywords: needsdocs