to_json() on a nested data structure containing undefined should not fail
Describe the bug
When calling to_json on an object like {foo: undefined}, it should result in {} and not panic. Here are some various behaviors (demo's using Node) which it would be good to follow:
> JSON.stringify({foo: undefined, bar: 1})
'{"bar":1}'
> JSON.stringify(undefined)
undefined
> JSON.stringify([1,2,undefined,4])
'[1,2,null,4]'
For context, I'm building a 3rd-party plugin system for Yaak using Boa and users may return a nested data structure that contain undefined values.
To Reproduce
Return an object from the JS context and call to_json on it.
export function callMe() {
return { foo: undefined };
}
Expected behavior
The value should serialize to {} and not throw not yet implemented: undefined to JSON.
Build environment (please complete the following information):
- OS: macOS
- Version: 14
- Target triple:
aarch64-apple-darwin - Rustc version:
rustc 1.77.2 (25ef9e3d8 2024-04-09)
Additional context
The current workaround is to return JSON.parse(JSON.stringify(objectContainingUndefineds)). However, as I'm using Boa to build a plugin system, I wouldn't expect users to have to do this themselves.
Another potential workaround is to recursively crawl the JSValue and remove undefined values from all the objects and arrays.
Thanks for taking the time to look into this!
I think the confusion here is that the to_json and from_json methods are misnomers; those functions just try to convert from serde_json's Value to Boa's JsValue, and since serde_json does not support "undefined", we cannot convert to it.
The solution here would be to expose JSON::stringify and JSON::parse as Rust APIs, and rename the serde_json APIs to to_serde_json_value and from_serde_json_value.
@gschier I'm not sure if I get it right, are you tying to call to_json in rust side with a JSValue::Object contains undefined and result in an error shows not yet implemented: undefined to JSON? As @jedel1043 explained, serde_json dose not allow convert value to undefined.
So what behavior is it expected to be?
I think what serde_json is doing is a Serde-specific implementation. boa should follow the spec and return {}.
I've created PR #4212 which I think handles undefined in a sensible way. Comments welcome.
Thanks for taking care of this!