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
- Run-time type checks (JS)
- Static / compilation type checks (TS)
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
- Run-time type checks (JS)
- Static / compilation type checks (TS)
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:
sizeshould 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'.
- Runtime type checks (JS)
- Static / compile-time type checks (TS)
| Assignment when | default defined | no 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)