Skip to content

v8.0.0

Compare
Choose a tag to compare
@paf31 paf31 released this 30 Jan 01:36
· 5 commits to master since this release

Breaking Changes

Encode Nothing as null rather than undefined

(@hdgarrood)

Previously, the Encode (Maybe a) instance was mapping Nothing to
undefined, which meant that Nothing fields in records would disappear
when stringifying:

-- old behaviour
newtype Foo = Foo { x :: Maybe Int }
derive instance genericFoo :: Generic Foo _

foo = Foo { x: Nothing }
log (encodeJSON foo)
-- {"tag":"Foo","contents":{}}

This commit changes the behaviour of the Encode (Maybe a) instance so
that Nothing is mapped to null rather than undefined. This means that
Nothing fields are present in the JSON, with a value of null:

-- new behaviour
log (encodeJSON foo)
-- {"tag":"Foo","contents":{"x":null}}

Note that we remain lenient about decoding records with Maybe fields:
a field may be present and have a value of null, or it may be absent;
in both cases, the field is decoded as Nothing.

This change brings foreign-generic more into line with Aeson, as by
default Aeson will also encode Nothing fields as present with a value of
null (in fact, this is configurable in Aeson: there is a configuration
option omitNothingFields which, when turned on, means that
Nothing-valued fields will be omitted during JSON encoding.)

Maybe values which ended up inside arrays in the encoded JSON are
unaffected by this change; previously they were mapped to null anyway.

Maybe values at the top level of the encoded JSON, however, are
affected. In fact, encoding Maybe values at the top level could
previously lead to runtime errors:

-- previously
> encodeJSON (Nothing :: Maybe Int)
./purescript-foreign-generic/.psci_modules/node_modules/Data.Show/foreign.js:30
  var l = s.length;
            ^

TypeError: Cannot read property 'length' of undefined

-- now
> encodeJSON (Nothing :: Maybe Int)
"null"