Skip to content

Instantly share code, notes, and snippets.

@leosuncin
Last active March 22, 2020 21:08
Show Gist options
  • Save leosuncin/c4e56120cb9a5b4522f89d1915dbe88a to your computer and use it in GitHub Desktop.
Save leosuncin/c4e56120cb9a5b4522f89d1915dbe88a 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 residents = [
{
familyName: 'Rhett Skiles',
houseNumber: '11A',
streetName: 'Goodwin Green',
contactPhone: '1101-7810',
contactEmail: 'goodwin_green@yopmail.com',
conmuteNumber: '111',
},
{
familyName: 'Velva Koelpin',
houseNumber: '12A',
streetName: 'Blick Roads',
contactPhone: '4198-4999',
contactEmail: 'blick_roads@yopmail.com',
conmuteNumber: '121',
},
{
familyName: 'Idell Mayer',
houseNumber: '13B',
streetName: 'Randy Island',
contactPhone: '7193-5209',
contactEmail: 'idell_mayer@yopmail.com',
conmuteNumber: '132',
},
{
familyName: 'Krystina Sipes',
houseNumber: '14C',
streetName: 'Jasper Forge',
contactPhone: '9416-0032',
contactEmail: 'krystina_sipes@yopmail.com',
conmuteNumber: '143',
},
{
familyName: 'Leilani Ward',
houseNumber: '21A',
streetName: 'Mabel Path',
contactPhone: '0139-0327',
contactEmail: 'leilani_ward@yopmail.com',
conmuteNumber: '211',
},
{
familyName: 'Tomasa Glover',
houseNumber: '22B',
streetName: 'Herman Views',
contactPhone: '5811-1680',
contactEmail: 'tomasa_glover@yopmail.com',
conmuteNumber: '221',
},
{
familyName: 'Bell Heller',
houseNumber: '23C',
streetName: 'Estevan Curve',
contactPhone: '7173-7339',
contactEmail: 'bell_heller@yopmail.com',
conmuteNumber: '233',
},
{
familyName: 'Kelli Cole',
houseNumber: '31A',
streetName: 'Gerhold Row',
contactPhone: '1873-4584',
contactEmail: 'kelli_cole@yopmail.com',
conmuteNumber: '311',
},
{
familyName: 'Lillian Orn',
houseNumber: '32B',
streetName: 'Kihn Place',
contactPhone: '3923-5371',
contactEmail: 'lillian_orn@yopmail.com',
conmuteNumber: '322',
},
{
familyName: 'Juliana Trantow',
houseNumber: '33C',
streetName: 'Donna Valley',
contactPhone: '3017-9615',
contactEmail: 'juliana_trantow@yopmail.com',
conmuteNumber: '333',
},
];
function isEmpty(text) {
return !Boolean(text);
}
const autocompleteConfig = {
id: 'autocomplete',
initial: 'idle',
context: {
query: '',
resident: undefined,
},
states: {
idle: {
initial: 'waiting',
states: {
waiting: {
on: {
'': {
target: '#autocomplete.searching',
cond: 'isQueryNotEmpty',
},
},
},
typing: {
after: {
500: 'waiting',
},
},
},
on: {
SET_QUERY: {
target: '.typing',
actions: 'setQuery',
},
},
},
searching: {
entry: 'clearErrorMessage',
invoke: {
src: 'searchResident',
onDone: [
{
target: '#autocomplete.loaded.empty',
cond: 'isDataEmpty',
},
{ target: '#autocomplete.loaded.list' },
],
onError: 'error',
},
},
loaded: {
entry: 'setResults',
initial: 'list',
states: {
list: {
on: {
SELECT_RESIDENT: {
target: 'selected',
actions: 'setResident',
},
},
},
empty: {},
selected: {},
},
on: {
SET_QUERY: {
target: '#autocomplete.idle.typing',
actions: 'setQuery',
},
},
},
error: {
entry: 'setErrorMessage',
on: {
SET_QUERY: {
target: '#autocomplete.idle.typing',
actions: 'setQuery',
},
},
},
},
};
const autocompleteOptions = {
actions: {
setQuery: assign((_, event) => ({
query: event.query,
})),
setResults: assign((_, event) => ({
results: event.data,
})),
setErrorMessage: assign((_, event) => ({
errorMessage: event.data.message,
})),
clearErrorMessage: assign(_ => ({
errorMessage: undefined,
})),
setResident: assign((_, event) => ({
resident: event.resident,
})),
},
guards: {
isQueryNotEmpty(context) {
return !isEmpty(context.query);
},
isDataEmpty(_, event) {
return (
!Array.isArray(event.data) ||
(Array.isArray(event.data) && event.data.length < 1)
);
},
},
services: {
searchResident({ query }) {
return new Promise((resolve, rejects) => {
const ilike = new RegExp(query, 'ig');
const results = residents.filter(
resident =>
ilike.test(resident.familyName) || ilike.test(resident.houseNumber),
);
setTimeout(() => {
if (/[^a-zA-Z0-9]/g.test(query)) {
rejects(new Error('This is an error'));
} else {
resolve(results);
}
}, 2e3);
});
},
},
};
const autocompleteMachine = Machine(autocompleteConfig, autocompleteOptions);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment