Enum fields

Schema.enum

Basic example

Let's suppose we're modelling a coffee order, which can either be an Americano, Latte or Cappucino.

Creation

import { ActiveClass, Schema } from 'fireactive'
const coffeeOrderSchema = {
type: Schema.enum(['Americano', 'Latte', 'Cappucino'])
}
class CoffeeOrder extends ActiveClass(coffeeOrderSchema) {}
new CoffeeOrder() // ActiveClassError: Could not construct CoffeeOrder. The required property 'type' is missing
new CoffeeOrder({}) // ActiveClassError: Could not construct CoffeeOrder. The required property 'type' is missing
new CoffeeOrder({ type: 'Herbal' }) // ActiveClassError: Could not construct CoffeeOrder. The property 'type' is of the wrong type
new CoffeeOrder({ type: null }) // ActiveClassError: Could not construct CoffeeOrder. The property 'type' is of the wrong type
new CoffeeOrder({ type: 'Americano', randomProp: 'Latte' }) // works (but randomProp gets ignored as it is not on the schema)
new CoffeeOrder({ type: 'Americano' }) // works
new CoffeeOrder({ type: 'Latte' }) // works

Assignment

import { ActiveClass, Schema } from 'fireactive'
const coffeeOrderSchema = {
type: Schema.enum(['Americano', 'Latte', 'Cappucino'])
}
class CoffeeOrder extends ActiveClass(coffeeOrderSchema) {}
const coffeeOrder = new CoffeeOrder({ type: 'Americano' })
coffeeOrder.type = 'Latte' // works
coffeeOrder.type = 'Orange juice' // ActiveClassError: CoffeeOrder could not accept the value "Orange juice" (string) at path 'type'. The property 'type' is of the wrong type
coffeeOrder.type = undefined // ActiveClassError: CoffeeOrder could not accept the value undefined (undefined) at path 'type'. The required property 'type' is missing
coffeeOrder.type = null // ActiveClassError: CoffeeOrder could not accept the value null (object) at path 'type'. The property 'type' is of the wrong type

Configuration

A schema property can have a default value, and/or be optional.

In either case, if the property has a default value and/or is optional, it does not need to be supplied when the ActiveDocument is created.

Default values are used when a field's value would otherwise be undefined.

Only optional properties can be assigned null (i.e. the deliberate ommission of a value).

Let's add some additionl properties to our coffeeOrder schema to demonstrate:

  • size should default to 'regular' but also accept 'small' and 'large';
  • chain, should be an optional property, but, if given, must be 'Starbucks', 'Costa' or 'Pret';
  • milk, should default to 'dairy' and be an optional property which, if given, must be 'dairy', 'oat' or 'soya'.
Assignment whendefault definedno default defined
required: true (default)
or optional: false
null: throws
undefined: uses default
null: throws
undefined: throws
optional: true
or required: false
null: uses null
undefined: uses default
null: uses null
undefined: uses undefined
import { ActiveClass, Schema } from 'fireactive'
const coffeeOrderSchema = {
type: Schema.enum(['Americano', 'Latte', 'Cappucino']),
size: Schema.enum(['small', 'regular', 'large'], { default: 'regular' }),
chain: Schema.enum(['Starbucks', 'Costa', 'Pret'], { optional: true }), // or required: false,
milk: Schema.enum(['dairy', 'oat', 'soya'], { optional: true, default: 'dairy' })
}
class CoffeeOrder extends ActiveClass(coffeeOrderSchema) {}
const coffeeOrder = new CoffeeOrder({ type: false })
coffeeOrder.type // => 'Americano'
coffeeOrder.size // => 'regular'
coffeeOrder.chain // => undefined
coffeeOrder.milk // => 'dairy'
/* type: required and no default */
coffeeOrder.type = undefined // ActiveClassError: CoffeeOrder could not accept the value undefined (undefined) at path 'type'. The required property 'type' is missing
coffeeOrder.type = null // ActiveClassError: CoffeeOrder could not accept the value null (object) at path 'type'. The property 'type' is of the wrong type
/* size: required and has default */
coffeeOrder.size = undefined
coffeeOrder.size // => 'regular' (default kicks in when undefined)
coffeeOrder.size = null // ActiveClassError: CoffeeOrder could not accept the value null (object) at path 'size'. The property 'size' is of the wrong type
/* chain: optional and has no default */
coffeeOrder.chain = undefined
coffeeOrder.chain // => undefined (optional, so doesn't throw, and has no default to kick in)
coffeeOrder.chain = null
coffeeOrder.chain // => null (optional, so doesn't throw and can be null)
/* milk: optional and has default */
coffeeOrder.milk = undefined
coffeeOrder.milk // => 'dairy' (default kicks in when undefined)
coffeeOrder.milk = null
coffeeOrder.milk // => null (optional, so doesn't throw and can be null)