JohnWeisz/TypedJSON

Option to preserve explicit null values when deserializing

Closed this issue · 7 comments

This is in some sense a companion to #100.

When decoding a JSON object which contains an explicit null value for a particular key, this key is completely omitted from the parsed object, just as if the key had not been present at all on the original object.

This is not ideal in some circumstances. For instance, in my case, we receive differential updates in JSON format. If a key is missing, this means "keep the previous value", but if it is present and explicitly null, that means "change the value to null"

This is actually a huge headache to represent in other languages, but given that JavaScript has given us the distinction of null vs undefined, it seems like it would make sense for the library to honor that distinction.

Looking at the source code, it seems this behavior is caused by this line in deserializer.js:

if (isValueDefined(revivedValue))
{
    sourceObjectWithDeserializedProperties[memberMetadata.key] = revivedValue;
}
else if (memberMetadata.isRequired)
{
    this._errorHandler(new TypeError(`Missing required member '${memberNameForDebug}'.`));
}

because isValueDefined() checks for both null OR undefined.

It would be pretty easy to change this to check for undefined only; I would be happy to submit a pull request. If on the other hand this is desired by default, perhaps a configuration option could be added? I could take a crack at that too.

This is something we'd love in our project too! I had to write a pretty messy workaround to re-iterate over the typedJsonJsonObjectMetadataInformation datamembers and populate any undefined properties (including sub-objects!)

Hey, good news (hopefully). I have finished the implementation, I want to double check it though so it should be out tomorrow. In the mean time, you can check out the candidate branch below. It works by specifying preserveNull option as true almost anywhere you want. With, hopefully, intuitive cascading (so a @jsonMember will overwrite a global setting).

https://github.com/JohnWeisz/TypedJSON/tree/candidate-1.4.0

Wow, this looks excellent, not only fixing the issue but also adding a framework for future cascading options!

One question/quibble - the docstring says "Whether to preserve null in the JSON output..." Does this option affect both parsing AND serializing? As it stands, the docstring makes me think serializing only. If so, that would solve #100 but not this issue.

Both actually. I will update the docs to make more clear. If you look at the added specs I test it both ways

1.4.0 was just release, to include this feature. Please, let me know, what you think.

@Neos3452 updated, implemented and works like a charm!

@jsonMember({preserveNull: true})
limitNum: number|null;

Thank you!

Same here, we replaced some kludge I had written with this new feature. Very clean!

Thanks for the quick turnaround!

Closing the issue.