Timeline for How do you JSON.stringify an ES6 Map?
Current License: CC BY-SA 4.0
27 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Nov 13, 2023 at 21:24 | comment | added | Malcolm |
This will convert map values of undefined to null because JSON.stringify does said conversion when undefined is found in an array. Stringifying a plain object omits the undefined value instead of converting. This also means that stringify and parse will result in non-equivalent maps. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
|
|
Mar 3, 2023 at 14:49 | comment | added | Stefnotch | @Pawel That's what I did down there :) | |
Mar 3, 2023 at 14:38 | comment | added | Pawel | @Stefnotch thanks for trying, but it does make the answer much harder to understand. The best will be if you post the modified version as a new answer | |
Mar 3, 2023 at 12:26 | comment | added | Stefnotch | @Pawel I submitted my edit, it makes the code slightly more complex, but should handle everything in a pretty bulletproof way. Let me know what you think. (And then we can clean up those comments here.) | |
Mar 3, 2023 at 12:25 | review | Suggested edits | |||
Mar 3, 2023 at 14:36 | |||||
Mar 2, 2023 at 18:46 | comment | added | Pawel | @Stefnotch that sounds like an architectural choice for a whole app so I don't see how a code change in this elementary transformation could handle this. Feel free to propse the change, although I find this answer simple and complete enough and reserve the right to undo the change if it makes the solution too complicated or the answer too verbose | |
Mar 2, 2023 at 18:32 | comment | added | Stefnotch | @Pawel In that case, may I edit your lovely answer to include a more bulletproof way of handling such cases? | |
Mar 2, 2023 at 18:07 | comment | added | Pawel |
@Stefnotch I agree that there could be a place that lets this slip through. i.e. a internal company npm package which is a wrapper for the api to pass some default options for auth headers and automatically parse JSON for convenience i.e. const getUrl = (url) => fetch(url, apiOptions).then(res => res.json()) where apiOptions have some global settings. It's worth remembering that such cases may happen and these must be adapted correctly
|
|
Mar 2, 2023 at 6:49 | comment | added | Stefnotch | It is entirely possible that I just worry too much about correctness though. Either way, I would prefer it if people copied bulletproof code that they can rely on. As such, I am absolutely allowing and encouraging you to tweak your answer to actually handle that case, or to just copy the code from my answer. :) | |
Mar 2, 2023 at 6:44 | comment | added | Stefnotch | Which raises the question "how would that happen". Here's one scenario: 1. customStringify( data ) and send it over the network 2. naive network handler automatically JSON decodes it <at this point you're not allowed to call customStringify followed by customParse on the object> 3. then we forward it, so we naively JSON encode it 4. customParse( data ) | |
Mar 2, 2023 at 6:34 | comment | added | Stefnotch |
It still does remain a footgun as is IMO. And there's apparently another sneaky case where it breaks. If one has some combination of the normal JSON parse , stringify and the customParse and customStringify from this answer, then one has to be really careful about how to apply them. Breakage could happen in a complex enough app with a backend and frontend. That is, customParse(customStringify( data )) works. So does customParse(stringify(parse(customStringify( data )))) . But customParse(stringify(customParse(customStringify(parse(customStringify( data ))))))) will break.
|
|
Mar 1, 2023 at 0:53 | comment | added | Pawel | @Stefnotch this could be exploited this way, but what's preventing anyone from changing any other data types in a payload i.e. [] to {} ? To prevent this validation is required and when a payload is validated it's happening after parsing so it becomes pretty clear that the field is not of object but map type | |
Jan 22, 2023 at 18:41 | comment | added | duttaoindril | You actually don't need to map.entries in the replacer, you can just array.from(map). | |
Oct 18, 2022 at 16:12 | comment | added | Pawel | @F.K.Juliano this is a "dangling comma" which is there at purpose for git diffs | |
Oct 18, 2022 at 16:06 | comment | added | F.K. Juliano | There is a misplaced comma in the replacer function: "value: Array.from(value.entries())," | |
Jul 28, 2022 at 16:52 | comment | added | Stefnotch | @mkoe I wrote an answer which actually fixes that problem. | |
Mar 21, 2022 at 13:49 | comment | added | Megajin |
If anyone is tempted to use Object.fromEntries() as stated in the MDN Docs I highly advise against it. You can parse a Map to an Object but not back! It will throw a object is not iterable error.
|
|
Sep 3, 2021 at 13:40 | comment | added | Pawel | @mkoe sure, but the probability of that is somewhere between being hit by a lightning and being hit by a lightning while hiding in a basement | |
Jul 15, 2021 at 19:42 | comment | added | mkoe | To me there seems to be a slight problem: any ordinary object o which by chance has the property o.dataType==='Map' will also be converted to a Map when you serialize-deserialize it. | |
Jan 27, 2021 at 9:35 | comment | added | Pawel | @JimiDini good point, updated. Now if someone wants to declare these as arrow functions it won't mess with the scope | |
Jan 27, 2021 at 9:33 | history | edited | Pawel | CC BY-SA 4.0 |
changed this[key] to value
|
Jan 21, 2021 at 14:59 | comment | added | JimiDini |
@Pawel what is the reason for using this[key] instead of value ?
|
|
Oct 9, 2020 at 21:52 | comment | added | Pawel | @rynop yeah it's more like a little program with it's own data storage format than just using pure native functionality | |
Oct 9, 2020 at 18:07 | comment | added | rynop |
Just marked this as correct. While I don't like the fact you have to "dirty up" the data across the wire with a non-standardized dataType , I can't think of a cleaner way. Thanks.
|
|
Oct 9, 2020 at 18:06 | vote | accept | rynop | ||
May 15, 2019 at 15:07 | history | edited | Pawel | CC BY-SA 4.0 |
deep nesting example
|
May 15, 2019 at 13:15 | history | answered | Pawel | CC BY-SA 4.0 |