Skip to content

Instantly share code, notes, and snippets.

@AndresRodH
Last active July 10, 2020 20:31
Show Gist options
  • Select an option

  • Save AndresRodH/ab3d3fe89413ee1d9c4a66bd03bc16cb to your computer and use it in GitHub Desktop.

Select an option

Save AndresRodH/ab3d3fe89413ee1d9c4a66bd03bc16cb to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// Available variables:
// - Machine
// - interpret
// - assign
// - send
// - sendParent
// - spawn
// - raise
// - actions
// - XState (all XState exports)
const basicsMachine = Machine({
id: 'petForm',
initial: 'ready',
context: {},
states: {
ready: {
on: {
START: 'basics.idle',
},
},
basics: {
on: {
NAME_INPUT: {
target: '.idle',
actions: assign({
name: (_, e) => e.value,
}),
},
BREED_INPUT: {
target: '.idle',
actions: assign({
breed: (_, e) => e.value,
}),
},
SUBMIT_BASICS: '.validating',
CANCEL_BASICS: {
target: 'ready',
actions: assign({
name: (_, _e) => undefined,
breed: (_, _e) => undefined,
}),
},
},
initial: 'idle',
states: {
idle: {},
invalid: {},
validating: {
invoke: {
id: 'validating',
src: (ctx) =>
new Promise((resolve, reject) => {
if (!ctx.breed) reject('Breed is required')
resolve()
}),
onDone: '#petForm.sex',
onError: 'invalid',
},
},
},
},
sex: {
on: {
GENDER_INPUT: {
target: '.idle',
actions: assign({
gender: (_, e) => e.value,
}),
},
SUBMIT_SEX: '.validating',
CANCEL_SEX: {
target: 'basics',
actions: assign({
gender: (_, _e) => undefined,
isNeutered: (_, _e) => undefined,
}),
},
},
states: {
idle: {},
invalid: {},
validating: {
invoke: {
id: 'validating',
src: (ctx) =>
new Promise((resolve, reject) => {
const errors = []
if (!ctx.gender) errors.push('Gender is required')
if (!ctx.isNeutered)
errors.push('Spayed/Neutered answer is required')
if (errors.length > 0) reject(errors)
resolve()
}),
onDone: '#petForm.age',
onError: 'invalid',
},
},
},
},
age: {
on: {
AGE_CATEGORY_INPUT: {
target: '.idle',
actions: assign({
ageCategory: (_, e) => e.value,
}),
},
SUBMIT_AGE: '.validating',
CANCEL_AGE: {
target: 'sex',
actions: assign({
ageCategory: (_, _e) => undefined,
}),
},
},
states: {
idle: {},
invalid: {},
validating: {
invoke: {
id: 'validating',
src: (ctx) =>
new Promise((resolve, reject) => {
if (!ctx.ageCategory) reject('Age Category is required')
resolve()
}),
onDone: '#petForm.weight',
onError: 'invalid',
},
},
},
},
weight: {
on: {
WEIGHT_INPUT: {
target: '.idle',
actions: assign({
weight: (_, e) => e.value,
}),
},
BCS_INPUT: {
target: '.idle',
actions: assign({
weight: (_, e) => e.value,
}),
},
SUBMIT_WEIGHT: '.validating',
CANCEL_WEIGHT: {
target: 'age',
actions: assign({
bcs: (_, _e) => undefined,
weight: (_, _e) => undefined,
}),
},
},
states: {
idle: {},
invalid: {},
validating: {
invoke: {
id: 'validating',
src: (ctx) =>
new Promise((resolve, reject) => {
const errors = []
if (!ctx.weight) errors.push('Weight is required')
if (!ctx.bcs) errors.push('Body Condition Score is required')
if (errors.length > 0) reject(errors)
resolve()
}),
onDone: '#petForm.activity',
onError: 'invalid',
},
},
},
},
activity: {
on: {
ACTIVITY_LEVEL_INPUT: {
target: '.idle',
actions: assign({
activityLevel: (_, e) => e.value,
}),
},
SUBMIT_ACTIVITY: '.validating',
CANCEL_ACTIVITY: {
target: 'weight',
actions: assign({
activityLevel: (_, _e) => undefined,
}),
},
},
states: {
idle: {},
invalid: {},
validating: {
invoke: {
id: 'validating',
src: (ctx) =>
new Promise((resolve, reject) => {
if (!ctx.activityLevel) reject('Activity Level is required')
resolve()
}),
onDone: '#petForm.region',
onError: 'invalid',
},
},
},
},
region: {
on: {
ZIP_CODE_INPUT: {
target: '.idle',
actions: assign({
zipCode: (_, e) => e.value,
}),
},
SUBMIT_ACTIVITY: '.validating',
CANCEL_ACTIVITY: {
target: 'activity',
actions: assign({
zipCode: (_, _e) => undefined,
}),
},
},
states: {
idle: {},
invalid: {},
validating: {
invoke: {
id: 'validating',
src: () =>
new Promise((resolve) => {
// region is optional
resolve()
}),
onDone: '#petForm.summary',
onError: 'invalid',
},
},
},
},
summary: {
on: {
SUBMIT: 'loading',
},
},
loading: {
invoke: {
id: 'submitting',
src: 'getRecommendedDiets',
onDone: 'success',
onError: 'failure',
},
},
failure: {
on: {
RETRY: 'loading',
},
},
success: {
type: 'final',
},
},
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment