Problem
NativeJsonInput (scala-commons, com.avsystem.commons.serialization.nativejs) only treats a missing key in a js.Dictionary / js.Object as "no value". A key that is present but set to undefined is reported as a real
field, which then fails to decode — typically with a ReadFailure — instead of being treated as absent.
This is surprising in a JS context: in JavaScript, { foo: undefined } and {} are effectively equivalent for property reads (obj.foo === undefined in both cases), and many JS-side producers emit undefined for optional
fields rather than omitting the key. As a result, payloads that round-trip through JS code (browser state, js.Dictionary built incrementally, libraries that set obj.foo = undefined for "no value") break deserialization
for fields that should be optional / have defaults.
Reproduction
val dict = js.Dictionary[js.Any]("foo" -> js.undefined)
val input = new NativeJsonInput(dict.asInstanceOf[js.Any], NativeFormatOptions())
GenCodec.read[CaseClassWithOptionalFoo](input) // fails on "foo"
vs. the working case:
val dict = js.Dictionary[js.Any]() // "foo" not set at all
// reads fine — `foo` falls back to default / Opt.Empty
Expected
NativeJsonInput should treat field: undefined the same as a missing field:
ObjectInput.hasNext / nextField should skip entries whose value is js.isUndefined.
ObjectInput.peekField(name) should return Opt.Empty when the key is present but its value is undefined, in addition to the key-not-present case.
Problem
NativeJsonInput(scala-commons, com.avsystem.commons.serialization.nativejs) only treats a missing key in ajs.Dictionary/js.Objectas "no value". A key that is present but set toundefinedis reported as a realfield, which then fails to decode — typically with a
ReadFailure— instead of being treated as absent.This is surprising in a JS context: in JavaScript,
{ foo: undefined }and{}are effectively equivalent for property reads (obj.foo === undefinedin both cases), and many JS-side producers emitundefinedfor optionalfields rather than omitting the key. As a result, payloads that round-trip through JS code (browser state,
js.Dictionarybuilt incrementally, libraries that setobj.foo = undefinedfor "no value") break deserializationfor fields that should be optional / have defaults.
Reproduction
vs. the working case:
Expected
NativeJsonInputshould treat field: undefined the same as a missing field:ObjectInput.hasNext/nextFieldshould skip entries whose value isjs.isUndefined.ObjectInput.peekField(name)should returnOpt.Emptywhen the key is present but its value isundefined, in addition to the key-not-present case.