Optional / null values

By design, all fields are required, ie. null or missing fields will cause a TypeError while reviving. In the case of the Animal class from the introductory example:

const pet = M.fromJSON(Animal, '{"name": null}')
// => TypeError: no value for key "name"

To support missing properties or null values, you can either use withDefault or declare the property as a Maybe

Using withDefault

The withDefault metadata takes some metadata and a default value which will be used only if the property is null or missing.

import M from 'modelico'
const {string, maybe} = M.metadata()

class Animal extends M.Base {

  // ... same as before

  static innerTypes () {
    return Object.freeze({
      name: withDefault(string(), 'Unknown')
    })
  }
}

Then, it can be used as any other value:

const pet1 = M.fromJSON(Animal, '{"name": "Bane"}')
const pet2 = M.fromJSON(Animal, '{"name": null}')
const pet3 = M.fromJSON(Animal, '{}')

pet1.name() // => Bane
pet2.name() // => Unknown
pet3.name() // => Unknown

Maybes

import M from 'modelico'
const {string, maybe} = M.metadata()

class Animal extends M.Base {

  // ... same as before

  static innerTypes () {
    return Object.freeze({
      name: maybe(string())
    })
  }
}

Then, we can use it as follows:

const pet1 = M.fromJSON(Animal, '{"name": "Bane"}')
// pet2 and pet3 behave the same way
const pet2 = M.fromJSON(Animal, '{"name": null}')
const pet3 = M.fromJSON(Animal, '{}')

pet1.name().isEmpty()         // => false
pet1.name().getOrElse('Coco') // => Bane
JSON.stringify(pet1)          // => {"name":"Bane"}

pet2.name().isEmpty()         // => true
pet2.name().getOrElse('Bane') // => Bane
JSON.stringify(pet2)          // => {"name":null}

pet3.name().isEmpty()         // => true
pet3.name().getOrElse('Bane') // => Bane
JSON.stringify(pet3)          // => {"name":null}

Note: pet2 does not produce the same JSON it was parsed from. If that is important to you, one possibility would be to not declare the name field and use M.fields(pet2).name to check for its presence and value manually.

Last updated