Skip to content

Instantly share code, notes, and snippets.

@devstojko
Last active March 22, 2020 04:03
Show Gist options
  • Select an option

  • Save devstojko/0003b59614c645351e51665831785ea3 to your computer and use it in GitHub Desktop.

Select an option

Save devstojko/0003b59614c645351e51665831785ea3 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 onFetchTripsSuccess = assign({
basket: (ctx, e) => ({
...ctx.basket,
selectedCompanies: Array(e.data && e.data.tripsWithDictionary.length).fill("")
}),
trips: (_, e) => e.data && e.data.tripsWithDictionary
});
const steps = {
one: {
valid: false,
completed: false,
companies: []
},
two: {
valid: false,
completed: false
},
three: {
valid: false,
completed: false
}
}
const WITHOUT_FIRST_TRIP = "https://api.myjson.com/bins/yacvc";
const fetchTrips = (ctx, e) => {
console.log('CTX', {ctx, e})
return fetch(WITHOUT_FIRST_TRIP).then(response => response.json());
}
const stepMachine = Machine({
id: 'stepMachine',
initial: 'stepOne',
context: {
locations: [],
trips: [],
basket: {
allowedCompany: null,
valid: false,
selectedCompanies: ["", "", ""]
},
tripQuery: {
type: "SINGLE",
passengers: 1,
vehicles: 0,
},
steps,
},
states: {
stepOne: {
initial: 'success',
states: {
idle: {
on: {
SEARCH: {
target: 'searching'
}
},
},
searching: {
invoke: {
id: 'getTrips',
src: 'fetchTrips',
onDone: {
target: 'success',
actions: 'onFetchTripsSuccess'
},
onError: {
target: 'error',
actions: assign({ error: (ctx, e) => event.data })
}
}
},
success: {
on: {
NEXT: {
target: '#stepMachine.stepTwo',
actions: 'submitOne',
cond: 'isBasketValid',
},
SEARCH: {
target: 'searching'
},
SELECT_COMPANY: {
actions: 'selectCompany'
},
}
},
error: {
},
},
on: {
TO_STEP_2: {
target: 'stepTwo',
cond: 'isOneCompleted'
},
TO_STEP_3: {
target: 'stepThree',
cond: 'isTwoCompleted'
},
SET_TRIP_QUERY: {
actions: 'setTripQuery',
cond: 'isValidTripQueryData'
}
}
},
stepTwo: {
on: {
NEXT: {
target: 'stepThree',
actions: 'submitTwo',
},
TO_STEP_1: {
target: '#stepMachine.stepOne.success',
cond: 'isOneCompleted'
},
TO_STEP_3: {
target: 'stepThree',
cond: 'isTwoCompleted'
}
}
},
stepThree: {
on: {
TO_STEP_2: {
target: 'stepTwo',
cond: 'isTwoCompleted'
},
TO_STEP_1: {
target: '#stepMachine.stepOne.success',
cond: 'isOneCompleted'
}
}
}
}
}, {
actions: {
onFetchTripsSuccess,
selectCompany: assign({
basket: (ctx, e) => {
let selectedCompanies = [...ctx.basket.selectedCompanies]
selectedCompanies[e.idx] = e.value;
const valid = ctx.basket.allowedCompany && selectedCompanies.every(company => company === ctx.basket.allowedCompany)
const allowedCompany = e.idx === 0 ? e.value : ctx.basket.allowedCompany
return ({
valid,
allowedCompany,
selectedCompanies
})
}
}),
submitOne: assign({
steps: ctx => ({
...ctx.steps,
one: {
completed: true
}
})
}),
submitTwo: assign({
steps: ctx => ({
...ctx.steps,
two: {
completed: true
}
})
}),
setTripQuery: assign({
tripQuery: (ctx, e) => ({
...ctx.tripQuery,
[e.name]: e.payload
})
}),
goBack: () => console.log('go back'),
submit: () => console.log('submit')
},
guards: {
isOneValid: ctx => ctx.steps.one.valid,
isOneCompleted: ctx => ctx.steps.one.completed,
isTwoCompleted: ctx => ctx.steps.two.completed,
isThreeCompleted: ctx => ctx.steps.three.completed,
isValidTripQueryData: (_, e) => e.name === "type" || e.name === "passengers" || e.name === "vehicles",
isBasketValid: ctx => ctx.basket.valid
},
services: {
fetchTrips
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment