Converting string obtained from element's data attribute to json - javascript

I get an error with the following code. I know $.parseJSON() is sensitive to single/double quotes. I cannot think of a solution to this problem. Can you please help !
<div data-x='{"a":"1","b":"2"}'></div>
$(document).ready(function(){
var data =$.parseJSON($("div").data("x"))
alert(data.a)
})
https://jsfiddle.net/r2Lnfbpm/

jQuery's data() does type conversion, so when the data attribute is valid JSON, it's already parsed into an object, and passing an object to $.parseJSON produces an error, as it expects a string of JSON.
$(document).ready(function(){
var data = $("div").data("x");
console.log(data.a);
});
From the documentation
Every attempt is made to convert the string to a JavaScript value
(this includes booleans, numbers, objects, arrays, and null).
A value is only converted to a number if doing so doesn't change the value's
representation.
For example, "1E02" and "100.000" are equivalent as
numbers (numeric value 100) but converting them would alter their
representation so they are left as strings. The string value "100" is
converted to the number 100.
When the data attribute is an object (starts with '{') or array
(starts with '[') then jQuery.parseJSON is used to parse the string;
it must follow valid JSON syntax including quoted property names. If
the value isn't parseable as a JavaScript value, it is left as a
string.
To retrieve the value's attribute as a string without any attempt to
convert it, use the attr() method.

Related

JavaScript JSON.parse string bug - convert value to Infinity

Can anyone explain me this strange behavior in JSON.parse() function in Javascript?
When calling it with string, it should raise an error.
e.g
JSON.parse("5ffc58ed1662010012d45b30");
result with:
VM230:1 Uncaught SyntaxError: Unexpected token f in JSON at position 1
at JSON.parse (<anonymous>)
at <anonymous>:1:6
...
BUT!!
When I call it with this specific value:
JSON.parse("60000528880e130012727947");
It return Infinity??? Why??? How this possible? What so special in this string?
Is this because this string is entirely consisting numbers and e in the middle? so JSON.parse thinks it's a kind of float?
JSON is a text representation of same data, usually a structure like an array or an object but a primitive value like a string or a number can also be represented as JSON without problems.
Being a text, in the source code it is represented as a JavaScript string.
The line:
JSON.parse("60000528880e130012727947");
can be as well JSON.parse(x), where x is a variable that contains the JSON.
The JSON in the example above is exactly this: 60000528880e130012727947 (there are no quotes around it, the quotes are the way a text is represented in the JavaScript source code). It is the text representation of a real number, 60,000,528,880 * 10^130,012,727,947, to be more precise.
JavaScript uses double-precision 64-bit binary format IEEE 754 to represent the number. The largest value a Number can hold is about 1.8×10^308 which is very much for most practical purposes. However, it is a small value compared to the value you have represented as JSON.
Anyway, no matter how large it is, since the value stored as JSON is larger than the greatest value that can be represented using the 64-bit double-precision format, Infinity is used instead.
Regarding the other example, 5ffc58ed1662010012d45b30 is not a valid representation of a number, therefore the JSON parser throws an error when it reaches the first f character at index 1.
All in all, JSON.parse() works fine, your input is not always valid JSON.
Basically it is considering the second string as a big number

SVG.js group is returning exponential value although I'm storing it as a string in group

Storing numeric value as String in group(some attribute) using SVG.js. How to get value as string instead of numeric exponential value.Although I'm converting value to String before adding to group. While re-fetching, group is giving exponential. How to avoid this?
Copied over from my comment:
svg.js tries to guess if the attribute you wanna get is from type number. If so, it uses parseFloat to return a number to you. If you want to have back the string value of the number use viewGroup.node.getAttribute('myVal')

What is a JSON-safe object?

In Kyle Simpson's book You Don't Know JS: this & Object Prototypes, he writes this on the subject of how to duplicate an object:
One subset solution is that objects which are JSON-safe (that is, can be serialized to a JSON string and then re-parsed to an object with the same structure and values) can easily be duplicated with:
var newObj = JSON.parse( JSON.stringify( someObj ) );
Of course, that requires you to ensure your object is JSON safe. For some situations, that's trivial. For others, it's insufficient.
What is a "JSON-safe" object? I ran a few tests with JavaScript and so far most things (arrays, numbers, strings, objects) can be duplicated using the above line, except for methods (foo.bar), when trying to duplicate a method, undefined is inserted in the method's place in the duplicated object.
To get foo<=> JSON.parse(JSON.stringify(foo)) as true, we must be able to represent foo in the JSON format.
JSON only supports:
Number: a signed decimal number that may contain a fractional part and may use exponential E notation, but cannot include non-numbers like NaN. The format makes no distinction between integer and floating-point. JavaScript uses a double-precision floating-point format for all its numeric values, but other languages implementing JSON may encode numbers differently.
String: a sequence of zero or more Unicodecharacters. Strings are delimited with double-quotation marks and support a backslash escaping syntax.
Boolean: either of the values true or false
Array: an ordered list of zero or more values, each of which may be of any type. Arrays use square bracket notation with elements being comma-separated.
Object: an unordered collection of name/value pairs where the names (also called keys) are strings. Since objects are intended to represent associative arrays,[12] it is recommended, though not required,[13] that each key is unique within an object. Objects are delimited with curly brackets and use commas to separate each pair, while within each pair the colon ':' character separates the key or name from its value.
null: An empty value, using the word null
In javascript, the concept of JSON safe object basically refers to a javascript object that can be represented in the JSON format without any loss.

What format is this object's key stored in? %00*%00_data

I have an object with the following key:
*_data
However, the characters are encoded in a non-standard format that is causing my code some problems.
I saved the value of the key to a cookie, and found the following:
%00*%00_data
However, when comparing this string (using == not ===) with the value of the key, they are not equal.
Currently I am storing the key's value into a variable and using that variable as the key. However, I'm extremely curious as to what string I could compare the actual key with that would result in true.
Any help with this mystery would be greatly appreciated.
%00 is the URI-encoded UTF-8 representation of the character NUL, representing the null character. I imagine this is used here to differentiate between the actual * character and a * character which may be replaced by some library you're using.
We can get from %00*%00_data to *_data by using JavaScript's decideURIComponent() method, which, as the name suggests, decodes the URI-encoded character:
decodeURIComponent("%00*%00_data");
Based on your comments, it seems that the key variable you're comparing against is actually this string of length 8. I mention this, because the string *_data you've included in your question is of length 6, as it doesn't include the two null characters.

alpha-numeric identifier causing problems

I am using a basic identifier which uses a unix timestamp with an appended alphanumeric section appended to it.
Everything has been working fine until recently - a couple of identifiers fail to update in the database.
I have noticed that the failing id's have all numbers and the letter E.
EG 1386953039E87 which is being transcribed as 1.386953039e+96
I am far from being a mathematician but feel that the original value is being treated as a number. I have tried using the toString() function but this has not worked for me.
Calling toString is too late because outputting 1386953039E87 has already created it as a number (or JavaScript's best guess at a number).
Try modifying your server-side code to output it surround in quotes instead, so that it gets created as a string instead of a number.
This could also be a side-effect of using jQuery's data() function. They mention in their api docs that it doesn't alter their value but it seems like your situation is proving otherwise:
Every attempt is made to convert the string to a JavaScript value
(this includes booleans, numbers, objects, arrays, and null). A value
is only converted to a number if doing so doesn't change the value's
representation. For example, "1E02" and "100.000" are equivalent as
numbers (numeric value 100) but converting them would alter their
representation so they are left as strings. The string value "100" is
converted to the number 100.
When the data attribute is an object (starts with '{') or array
(starts with '[') then jQuery.parseJSON is used to parse the string;
it must follow valid JSON syntax including quoted property names. If
the value isn't parseable as a JavaScript value, it is left as a
string.
To retrieve the value's attribute as a string without any attempt to
convert it, use the attr() method.
So it seems you need to use the attr() instead of data() for this

Categories