Skip to main content

Bug Tracker

Side navigation

#11060 closed enhancement (duplicate)

Opened December 19, 2011 09:42PM UTC

Closed January 11, 2012 04:21PM UTC

Last modified July 15, 2013 03:07PM UTC

Proposal to change the design of .data() slightly

Reported by: latchkey@gmail.com Owned by:
Priority: undecided Milestone: None
Component: unfiled Version: 1.7.1
Keywords: Cc:
Blocked by: Blocking:
Description

Dear jQuery experts and my mentors:

I know that this has been brought up multiple times in other ways, but I'm going to bring it up again, in hopefully a different way, so please be kind enough to hear me out.

Suppose you have this:

.data('foo', 'bar')

.data('foo') === 'bar'

Ok, no big deal. String in, string out.

.data('ack', 1.400)

.data('ack') === 1.4

Yes, I'm well aware that putting a float will return me a float, who's value will lose the precision of the two 0's. That is fine, no big deal.

The issue I'm having with .data is when the values of data are assigned from an element in the DOM like this:

<button data-id="1.400"></button>

data('id') === 1.4 (the float, instead of the string 1.400)

What I would like to propose is that:

#1. .data() be changed to always return the same type of what goes into data()

#2. make what goes into data(), from elements, always be a string since you can't really assume what the type is or assume that you are doing a conversion here.

This will do four major things:

#1. not break existing code. we can't have that.

#2. negate the need to use attr() to retrieve the unmolested value of data() from elements.

#3. prevent me from having to write everything as data-id="'1.400'" (using single quotes). this is arguably very error prone.

#4. remove a potentially bug inducing bit of design. if i suddenly decide to change my id from an integer to a float (this happened recently, so that is what brought this up, so i know it is a real world issue).

Again, I thank you for your time and patience and understanding.

Attachments (0)
Change History (10)

Changed January 11, 2012 04:21PM UTC by dmethvin comment:1

resolution: → duplicate
status: newclosed

Changed January 11, 2012 04:21PM UTC by dmethvin comment:2

Duplicate of #7579.

Changed July 17, 2012 09:26PM UTC by anonymous comment:3

This seems ok to you?

http://jsfiddle.net/rKnFu/

I'm trying to store a number as hex, but jquery assumes I really meant exponential notation? WTF?

Changed July 17, 2012 10:16PM UTC by rwaldron comment:4

Use attr()

Changed August 31, 2012 09:35AM UTC by jeremy.lecour@gmail.com comment:5

I'm honestly not trolling here, but this is pretty much like what PHP does ; automatic type-guessing without a proper way to tell it how to do it. IMHO it's bad

At least in JSON we have a syntax to indicate the type.

I'd like to have .data() to always return a string and have convenient helpers to easily/manually change the type if needed.

Using .attr() is a good replacement for .data() in many cases, especially if you want a read/write behavior and expect to reflect the value in the "real" html attribute.

But some times, you want the benefit of .data(), but this type mess.

Changed August 31, 2012 01:11PM UTC by dmethvin comment:6

I'd like to have .data() to always return a string and have convenient helpers to easily/manually change the type if needed.

You mean if someone set a Boolean using .data("visited", false) we would return the string "false" for .data("visited")? Go think about the havoc that would cause to existing code.

Changed August 31, 2012 04:56PM UTC by latchkey comment:7

As the submitter of this ticket, I do NOT agree with what Jeremy just said.

I think that .data() should *always* return what you put into it. But, any element attribute which was written in HTML, not via JS dom manipulation, ie: <div data-foo="">, should return String since casting is dangerous and unreliable in this case. There is no type information that can be assumed, other than String, and existing behavior cannot work correctly for all cases.

fyi, my blog posting on this has received over 10k views. This is clearly an issue for a lot of people. It would be good if the JQuery community took it more seriously, but I'm not holding my breath.

Changed August 31, 2012 05:04PM UTC by dmethvin comment:8

latchkey, the majority of the confusion comes from the expectation that .data() is used ONLY to get and set data- attributes. Unfortunately, since the method predates HTML5 and data- attributes, it has different semantics and capabilities. If you look at the dup ticket #7579 referenced here, we tweaked things a bit in 1.8.0 to only convert something to a number if it wouldn't change the representation, so data-number="1.80000000" will stay a string since it would otherwise clip the zeroes.

I don't think there is anything we can do to meet everyone's expectations yet avoid breaking code. In any case, a closed duplicate ticket isn't a good place to discuss.

Changed July 15, 2013 06:46AM UTC by anonymous comment:9

I've got a case where a large number is stored as a data- attribute in the HTML. When you fetch the value using $.data, the coercion is buggering up the number and it breaks my code because I'm not getting back EXACTLY what has been put into the HTML.

For example:

<tr data-id="201319611370584515">etc</tr>

When I call .data to fetch that value, I get the integer value 201319611370584500 back and because I need that id to match elsewhere of course it fails.

If I place an alpha character at the beginning of the attribute, for example data-id="x201319611370584515", then I get back exactly what I put in there.

It's beyond me how this behaviour can be considered justifiable when you are dealing with a data format that is patently not typed (HTML). I can't see any rationalisation for it returning a different value to what actually appears in the HTML.

I guess I will use .attr but I think this peculiar behaviour with large numbers needs to be explicitly spelled out in the documentation (or even better fixed) because I had to Google this issue and came upon this bug by way of the blog post mentioned above after scratching my head for over an hour trying to work out what the hell was going on.

Changed July 15, 2013 03:07PM UTC by rwaldron comment:10

_comment0: Replying to [comment:9 anonymous]: \ > I've got a case where a large number is stored as a data- attribute in the HTML. When you fetch the value using $.data, the coercion is buggering up the number and it breaks my code because I'm not getting back EXACTLY what has been put into the HTML. \ > \ > For example: \ > \ > <tr data-id="201319611370584515">etc</tr> \ > \ > When I call .data to fetch that value, I get the integer value 201319611370584500 back and because I need that id to match elsewhere of course it fails. \ > \ > If I place an alpha character at the beginning of the attribute, for example data-id="x201319611370584515", then I get back exactly what I put in there. \ > \ > It's beyond me how this behaviour can be considered justifiable when you are dealing with a data format that is patently not typed (HTML). I can't see any rationalisation for it returning a different value to what actually appears in the HTML. \ > \ > I guess I will use .attr but I think this peculiar behaviour with large numbers needs to be explicitly spelled out in the documentation (or even better fixed) because I had to Google this issue and came upon this bug by way of the blog post mentioned above after scratching my head for over an hour trying to work out what the hell was going on. \ \ \ Stop being dramatic please. \ \ JavaScript numbers are IEEE standard #754, double-precision binary floating-point 64-bit numbers. This means that only even numbers greater then (2^53) are representable. jQuery had enough bug report/complaints about larger numbers (eg. 201319611370584515) being rounded that the only solution was to use a string to represent data values that were not representable as numbers. This way you get the actual value, despite the type being incorrect. \ 1373911098593164
_comment1: Replying to [comment:9 anonymous]: \ > I've got a case where a large number is stored as a data- attribute in the HTML. When you fetch the value using $.data, the coercion is buggering up the number and it breaks my code because I'm not getting back EXACTLY what has been put into the HTML. \ > \ > For example: \ > \ > <tr data-id="201319611370584515">etc</tr> \ > \ > When I call .data to fetch that value, I get the integer value 201319611370584500 back and because I need that id to match elsewhere of course it fails. \ > \ > If I place an alpha character at the beginning of the attribute, for example data-id="x201319611370584515", then I get back exactly what I put in there. \ > \ > It's beyond me how this behaviour can be considered justifiable when you are dealing with a data format that is patently not typed (HTML). I can't see any rationalisation for it returning a different value to what actually appears in the HTML. \ > \ > I guess I will use .attr but I think this peculiar behaviour with large numbers needs to be explicitly spelled out in the documentation (or even better fixed) because I had to Google this issue and came upon this bug by way of the blog post mentioned above after scratching my head for over an hour trying to work out what the hell was going on. \ \ \ This is already fixed, please upgrade your version of jQuery. \ \ JavaScript numbers are IEEE standard #754, double-precision binary floating-point 64-bit numbers. This means that only even numbers greater then (2^53) are representable. jQuery had enough bug report/complaints about larger numbers (eg. 201319611370584515) being rounded that the only solution was to use a string to represent data values that were not representable as numbers. This way you get the actual value, despite the type being incorrect.1373911143989663
_comment2: Replying to [comment:9 anonymous]: \ > I've got a case where a large number is stored as a data- attribute in the HTML. When you fetch the value using $.data, the coercion is buggering up the number and it breaks my code because I'm not getting back EXACTLY what has been put into the HTML. \ > \ > For example: \ > \ > <tr data-id="201319611370584515">etc</tr> \ > \ > When I call .data to fetch that value, I get the integer value 201319611370584500 back and because I need that id to match elsewhere of course it fails. \ > \ > If I place an alpha character at the beginning of the attribute, for example data-id="x201319611370584515", then I get back exactly what I put in there. \ > \ > It's beyond me how this behaviour can be considered justifiable when you are dealing with a data format that is patently not typed (HTML). I can't see any rationalisation for it returning a different value to what actually appears in the HTML. \ > \ > I guess I will use .attr but I think this peculiar behaviour with large numbers needs to be explicitly spelled out in the documentation (or even better fixed) because I had to Google this issue and came upon this bug by way of the blog post mentioned above after scratching my head for over an hour trying to work out what the hell was going on. \ \ \ This is already fixed, please upgrade your version of jQuery. \ \ JavaScript numbers are IEEE standard 754, double-precision binary floating-point 64-bit numbers. This means that only even numbers greater then (2^53) are representable. jQuery had enough bug report/complaints about larger numbers (eg. 201319611370584515) being rounded that the only solution was to use a string to represent data values that were not representable as numbers. This way you get the actual value, despite the type being incorrect.1373911261549983

Replying to [comment:9 anonymous]:

I've got a case where a large number is stored as a data- attribute in the HTML. When you fetch the value using $.data, the coercion is buggering up the number and it breaks my code because I'm not getting back EXACTLY what has been put into the HTML. For example: <tr data-id="201319611370584515">etc</tr> When I call .data to fetch that value, I get the integer value 201319611370584500 back and because I need that id to match elsewhere of course it fails. If I place an alpha character at the beginning of the attribute, for example data-id="x201319611370584515", then I get back exactly what I put in there. It's beyond me how this behaviour can be considered justifiable when you are dealing with a data format that is patently not typed (HTML). I can't see any rationalisation for it returning a different value to what actually appears in the HTML. I guess I will use .attr but I think this peculiar behaviour with large numbers needs to be explicitly spelled out in the documentation (or even better fixed) because I had to Google this issue and came upon this bug by way of the blog post mentioned above after scratching my head for over an hour trying to work out what the hell was going on.

This is already fixed, please upgrade your version of jQuery.

JavaScript numbers are IEEE standard 754, double-precision binary floating-point 64-bit numbers. This means that only even numbers greater then (2^53) are representable. jQuery had enough bug report/complaints about larger numbers (eg. 201319611370584515) being rounded that the only solution was to use a string to represent data values that were not representable as numbers. This way you get the actual value, despite the type being incorrect.