Reputation: 52758
In addition to strings and numbers, valid JSON can contain special values like null
and false
I need to parse a JSON generated by some API that also contains undefined
. However, undefined
is a valid JavaScript value, but it is not a valid JSON value, and whenever I parse it it returns a lexical error.
library(jsonlite)
# A string works
"[{\"Sepal.Width\":\"3.5\"}]" %>% fromJSON
# Sepal.Width
# 3.5
# A number works
"[{\"Sepal.Width\":3.5}]" %>% fromJSON
# Sepal.Width
# 3.5
# null works
"[{\"Sepal.Width\": null}]" %>% fromJSON
# Sepal.Width
# NA
# false works
"[{\"Sepal.Width\": false}]" %>% fromJSON
# Sepal.Width
# FALSE
# undefined does not work
"[{\"Sepal.Width\": undefined}]" %>% fromJSON
Error: lexical error: invalid char in json text.
[{"Sepal.Width": undefined}]
(right here) ------^
Is there any (reliable) way to parse JSON containing undefined
values? If not, what is the best approach to repair this faulty JSON?
I've thought about simply gsubbing undefined
, but that is risky, since that word could easily exist in the JSON string values.
Upvotes: 0
Views: 929
Reputation: 2592
undefined values are not valid as mentioned in previous answers, but if you are in a situation where you have no option but to handle it... You can use a placeholder value when stringifying and parsing
export function stringifyKeepingUndefined(obj: any): string {
if (!obj)
return obj;
return JSON.stringify(obj, (k, v) => (v === undefined) ? '__undefined' : v);
}
And
export function parseHandlingUndefined(json: any): any {
if (!json)
return json;
let parsed = JSON.parse(json);
const iterate = (obj: any) => {
Object.keys(obj).forEach(key => {
if (obj[key] === '__undefined') {
obj[key] = undefined;
}
if (typeof obj[key] === 'object' && obj[key] !== null) {
iterate(obj[key])
}
})
}
iterate(parsed);
return parsed;
}
Upvotes: 1
Reputation: 2613
Nope. You cannot parse a JSON with an undefined value; undefined is indeed a special value. In fact, undefined
as a "value" must not occur in valid JSON, and is intended to mean "this key [in your case, "Sepal.Width"
] doesn't exist." Instead, the API is likely faulty, where it is generating JSONs with undefined
values.
The official source, The JSON Data Interchange Syntax, states that
A JSON value can be an object, array, number, string, true, false, or null.
The best remedy is to examine the JSON generator or API and why it generates undefined
in a JSON. You can also manually or algorithmically repair the defective JSON, and check if there are any inconsistencies in your JSON.
Upvotes: 3
Reputation: 52758
For the record, I used str_replace_all()
to replace :undefined
with :"undefined"
.
This is somewhat risky because it will cause problems if the string :undefined
so happens to appear in actual string values in the JSON, but in my case it's (an imperfect) solution
str_replace_all(invalid_json, ':undefined', ':"undefined"')
Upvotes: 1