When persisting and then restoring state the nextEvents property is empty. However after doing a transition on the restored machine/state the nextEvents property is correct:
const machine = newMachine();
const savedState = JSON.stringify(machine.initialState);
const restoredStateDef = JSON.parse(savedState);
const restoredState: State<{ claim: any }, any> = State.create(
restoredStateDef
);
const restoredMachine = interpret(newMachine()).start(restoredState);
const currentState = restoredMachine.machine.transition(
restoredState,
Transition.next
);
Here are my console logs from the various states:
machine.initialState.nextEvents [ 'next' ]
restoredState.nextEvents []
restoredMachine.state.nextEvents []
currentState.nextEvents [ 'previous', 'next' ]
Please provide a full reproducible example, including machine definition.
Hello, demo in sandbox: https://codesandbox.io/s/505rj518nl
This is working as expected - the nextEvents are determined by the state machine itself (through the private state.tree) and this has the potential to make the saved state very large, especially when there are many event and other state nodes.
We can probably have something like...
// Tentative API
// instead of State.create(...)
const restoredState = machine.resolveState(restoredStateDef);
Which will use the machine to determine the state.tree, which will provide nextEvents, etc.
Thanks for looking at it. I agree that it's working correctly as after restoring the machine can transition correctly to the next state.
This is an issue for me because after persisting the state to storage and then later restoring it I need to display the nextEvents to the UI as it determines what gets painted on the screen. After which the user will do some action which corresponds to a transition.
A work around for me would be persisting the nextEvents to storage for now.
This caught me out as well. I'm working on a project that uses the nextEvents property to render buttons in the UI & makes use of save/ restore state when a user logs in/out. It would be helpful to have a method that restored a machine to exactly what it was.
ran into this snag too. going to try the workaround.
hmm it's easy enough to persist the nextEvents to localstorage etc, but there doesn't seem to be a way to set them on a state node (getter only)?
@geddski You can do this:
const persistedState = Object.defineProperty(state, 'nextEvents', {
value: state.nextEvents
});
as a workaround.
@davidkpiano smart! 馃挴
The machine.resolveState(state) API is implemented in master and will be documented 馃敎
The interpreter in the upcoming 4.4 will automatically resolve states:
// Will resolve { foo: 'bar' } to full state with nextEvents
service.start(State.from({ foo: 'bar' }));
// Same as above
service.start({ foo: 'bar' });
If you want to do this manually, use machine.resolveState(state):
// Given prevState is a State instance
const resolvedState = machine.resolveState(prevState);
// Otherwise use State.from()
const resolvedState = machine.resolveState(State.from(prevStateValue));
Most helpful comment
The interpreter in the upcoming 4.4 will automatically resolve states:
If you want to do this manually, use
machine.resolveState(state):