Skip to content

Instantly share code, notes, and snippets.

@JamieMason
Last active July 13, 2020 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamieMason/3b277df080742d0e93b032feaef1a397 to your computer and use it in GitHub Desktop.
Save JamieMason/3b277df080742d0e93b032feaef1a397 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const formMachine = Machine(
{
id: 'form',
initial: 'editing',
context: {
apiError: '',
formSchema: null,
formData: null,
},
states: {
editing: {
type: 'parallel',
on: {
CHANGE: {
actions: 'setValue',
},
},
states: {
validity: {
initial: 'hidden',
states: {
hidden: {
on: {
SUBMIT: 'evaluating',
},
},
evaluating: {
on: {
'': [
{
cond: 'hasInvalidFields',
target: 'invalid',
},
{
target: 'valid',
},
],
},
},
invalid: {
entry: 'focusOnErrors',
on: {
SUBMIT: 'evaluating',
},
},
valid: {
on: {
SUBMIT: 'evaluating',
},
},
},
},
apiClient: {
initial: 'idle',
states: {
idle: {
on: {
SUBMIT: [
{
cond: 'hasInvalidFields',
target: 'idle',
},
{
target: 'sending',
},
],
},
},
sending: {
invoke: {
id: 'sendForm',
src: 'sendForm',
onError: {
actions: 'setApiError',
target: 'rejected',
},
onDone: {
target: 'resolved',
},
},
},
resolved: {},
rejected: {},
},
},
},
},
complete: {
entry: 'onComplete',
type: 'final',
},
},
},
{
guards: {
hasInvalidFields: (ctx) => true,
},
actions: {
focusOnErrors: () => {
console.log('Call .focus() on list of validation errors');
},
setApiError: assign({
apiError: (ctx, event) => event.data.message,
}),
onComplete: (ctx) => {
if (ctx.shouldRememberMe === true) {
console.log('Set RememberMe Cookie to', ctx.email);
} else {
console.log('Ensure RememberMe Cookie is not set');
}
},
setValue: assign((ctx, { name, value }) =>
name in ctx
? {
...ctx,
[name]: value,
[`${name}Error`]: '',
}
: ctx
),
},
services: {
sendForm: apiThatOnlyWorksFor30SecondsEachMinute,
},
}
);
function apiThatOnlyWorksFor30SecondsEachMinute() {
return new Promise((resolve, reject) => {
setTimeout(() => {
new Date().getSeconds() < 30 ? resolve() : reject(new Error('500 Error'));
}, 2000);
});
}
// { "type": "SET_EMAIL", "email": "a@a.com" }
// { "type": "SET_REMEMBER_ME", "shouldRememberMe": true }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment