Skip to content

Instantly share code, notes, and snippets.

@airandopal
Last active November 19, 2019 03:35
Show Gist options
  • Save airandopal/bc0abefb5a7fa7e0ab5e2d991d6b2633 to your computer and use it in GitHub Desktop.
Save airandopal/bc0abefb5a7fa7e0ab5e2d991d6b2633 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// todo: move these to guards object in machine
const isError = (context, event) => {
return context.isError;
};
const isNoError = (context, event) => {
return context.noError;
};
const isComplete = (context, event) => {
return context.isComplete;
};
const stripeElement = {
id: "stripeElement",
initial: "empty",
states: {
empty: {
on: {
// this might need conditions
SE_CHANGE: "noError"
}
},
noError: {
on: {
// didnt know how else to change context in the visualizer...
HELPER: {
actions: assign({ isComplete: true })
},
SE_CHANGE: [
{ target: "error", cond: isError },
{ target: "noError", cond: isNoError },
{ target: "complete", cond: isComplete },
{ target: "noError" }
]
}
},
error: {
on: {
// conditions...
// CHANGE: [],
SE_ERROR: "error",
SE_NO_ERROR: "noError"
}
},
complete: { type: "final" }
}
};
const cardholderName = {
id: "cardholderName",
initial: "empty",
states: {
// from empty it can only go to noError becaue once one letter is typed it would be an error
empty: {
on: {
// this might need conditions
CN_CHANGE: "error"
}
},
noError: {
on: {
CN_ERROR: "error",
CN_NO_ERROR: "noError",
CN_VALID: "valid"
}
},
error: {
on: {
// conditions...
// CHANGE: [],
CN_ERROR: "error",
CN_NO_ERROR: "noError"
}
},
valid: { type: "final" }
}
};
// todo: use only elementStates, not isComplete [currently used with assign helper in testing]
const context = {
mountedElement: null,
elementStates: {
error: null,
complete: null,
empty: null
},
cardholderName: '',
setupIntent: null,
isComplete: false,
retries: 0,
stripeElementLoadAttempts: 0,
}
const fetchMachine = Machine({
id: 'fetch',
initial: 'closed',
context,
states: {
closed: {
on: {
// user clicks button to reveal the form
OPEN: 'loading'
}
},
// this is where things are being created, call to get a setup intent, etc. loading / creating the form
// seems like this needs to invoke and then onDone or onError move along accordingly
loading: {
on: {
SUCCESS: 'editPhase',
FAIL: 'failedUI'
}
},
editPhase: {
id: "fields",
type: "parallel",
onDone: "readyToSubmit",
states: {
stripeElement,
cardholderName
}
},
readyToSubmit: {
on: {
SUBMIT: 'submitting'
}
},
// on, success, move to submitted good submission
submitting: {
on: {
GOOD_RESPONSE: 'submitted.goodSubmission',
BAD_RESPONSE: 'submitted.failedSubmit'
}
},
failedUI: {
on: {
// todo: retry a few times and if failed all those times then reportbug and exit and do not allow to return for x amount of time?
RETRY: 'loading', // or should be editing
EXIT: '#fetch.closed', // this actually needs to exit the whole component
// maybe
SEND_FEEDBACK: '#reportBug'
}
},
// did have it in submitted, but from failed ui might need to report bug. [is report bug a parallel state, would anythinge else be open when its showing?]
reportBug: {
// onEntry show reportBug modal...
id: 'reportBug'
},
submitted: {
id: 'submitted',
states: {
failedSubmit: {
on: {
// requires guards
RETRY: {},
// this might be wehre i invoke another machine - the report bug form machine
SEND_FEEDBACK: '#reportBug',
EXIT: '#fetch.closed'
}
},
// is this really final tho? wouldnt closed be a final? answer: thats what exit action can do.
goodSubmission: {
type: 'final',
// use a timeout for effect?
exit: 'closeForm'
}
},
},
},
on: {
// aka cancel, clear / need onExit here to perform clearing of the form - do i need a new setup intent in some cases? is that a case / guard to handle
// reset will reset form but does not exit
// cancel/exit will kill form, unmount stripe elements etc, and close the component back to the button. should also do entry and exit analytics like mark cancelled setup intent etc.
RESET: 'editPhase',
CANCEL: 'closed',
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment