5

I am building a Node backend which pulls data from the Vine API, and returns this to my front end. The IDs for posts and users are of type Number, and they frequently exceed the maximum integer that javascript can support, according to this question.

An example ID from the API is 934416748524998656. When I use JSON.parse on the front end it replaces those last 2 digits with 0, because it can't read a number that high This causes problems when I try to talk to the API with specific IDs, as it now doesn't recognise the ID.

Is there anything, short of creating a new service in another language, that I can do to work with these IDs? I tried using toString() to interpret the numbers as strings instead, but that just creates a string of the already malformed number.

Thanks for any help

Community
  • 1
  • 1
Jonathon Blok
  • 749
  • 4
  • 14
  • 1
    How are you getting these numbers? Are they coming in a JSON document and you're just parsing that and that's creating the malformed numbers? – tkone Aug 12 '14 at 16:28
  • Yes, they are within a JSON response from the Vine API - [see example](https://api.vineapp.com/timelines/tags/dogs). Once I parse them on the front end, they break – Jonathon Blok Aug 12 '14 at 16:32
  • @JonathonBlok I think this is a great question -- please include that precise technical information in your question (i.e., explain you're using `JSON.parse` on JSON that contains too-big-for-JS numbers). – apsillers Aug 12 '14 at 16:35
  • Closely related is [JSON transfer of bigint: 12000000000002539 is converted to 12000000000002540?](http://stackoverflow.com/q/8663298/710446), but that is a case in which the asker has control over the server data format. – apsillers Aug 12 '14 at 16:38
  • proof that JSON!=JS. i figured JSON would be locked into 64 bit numbers, but i checked the spec and there's nothing more specific than "Number"... still, dumb of vine to use them... – dandavis Aug 12 '14 at 16:38
  • @dandavis Indeed: http://stackoverflow.com/questions/13502398/json-integers-limit-on-size – apsillers Aug 12 '14 at 16:39
  • 2
    since i doubt you need to do math on them, just turn them into strings before you parse: JSON.parse(strJson.replace(/\: (\d{17,},)/g,': "$1",')); – dandavis Aug 12 '14 at 16:48
  • @apsillers question updated. @dandavis That seems like it should do the trick. Really, it doesn't make a difference to me if it's a Number or String. I'm getting an error in node when trying this however `SyntaxError: Unexpected number at Object.parse (native)`. Do you know what might cause that? – Jonathon Blok Aug 12 '14 at 17:00
  • @dandavis apologies, I hadn't seen you'd updated the regex! Works perfectly, thanks very much! – Jonathon Blok Aug 12 '14 at 17:02
  • 1
    @dandavis Your code is a pretty sound idea, but the trailing comma is included in your `$1` capture group. Just move the comma outside the parentheses, and I'd say post that as an answer (with a caveat that it's a bit of a hack that might break on rare occasions as noted in the comment below). – apsillers Aug 12 '14 at 17:02
  • Converting to string is the real solution, just be careful with the regex, for it may accidentally match something else (such as number after colon, that's in a string). – MightyPork Aug 12 '14 at 17:04
  • there was a typo in my code, see answer for the right one... – dandavis Aug 12 '14 at 17:05

1 Answers1

5

change the number into a string before parsing:

var responseData = JSON.parse(
   strJson.replace(/\: (\d{17,}),/g,': "$1",')
);

note this will falsely modify any string data that contains a big number that looks like a json value, but i'd call that a worthy tradeoff compared to the deep-investment alternatives. still, it's not just a big number that hits, but (": " + theNumber +","); the only time i can imagine that happening is someone "re-tweeting" the JS-invalid API response. use a parser if you care that much about being perfect.

dandavis
  • 16,370
  • 5
  • 40
  • 36
  • A workaround for the tradeoff is to parse it char-by-char, collect whole strings, and replace only sequences of numbers that are not in string. – MightyPork Aug 12 '14 at 17:06
  • @MightyPork: yeah a FSM or even block parser like jsmin could fix the limit, but i'd consider that "deep-investment". still, much worth a mention, thanks. – dandavis Aug 12 '14 at 17:07
  • damn you, I googled FSM and ended up here: http://en.wikipedia.org/wiki/Flying_Spaghetti_Monster :D – MightyPork Aug 12 '14 at 17:20
  • doh! i was talking about a ".charAt()" Finite State Machine: http://en.wikipedia.org/wiki/Finite-state_machine ... – dandavis Aug 12 '14 at 17:27