xstate-viz icon indicating copy to clipboard operation
xstate-viz copied to clipboard

`onDone` not working when the child state is final.

Open veeramarni opened this issue 2 years ago • 0 comments

Description

This issue happens in xstate-viz only but in the vscode xstate plugin works fine. When the child state is final, the parent's onDone need to be enabled and when onDone even is called it should go back to idle state but it just hangs in the visualizer without doing anything.

example

import { createMachine, assign } from 'xstate';

interface IngetrationContext {
    step: number;
    submittedData: any[];
}
export const test =
    createMachine(
        {
            context: {
                step: 0,
                submittedData: [],
            },
            initial: 'idle',

            states: {
                idle: {
                    always: [
                        { target: 'step1', cond: 'didStep1' },
                        { target: 'step2', cond: 'didStep2' },
                    ],

                    on: {
                        NEXT: [
                            {
                                target: 'idle',
                                cond: (ctx, event) => event.data !== '',
                                actions: 'incrementStep',
                            },
                            {
                                target: 'error',
                            },
                        ],

                        // ERROR: "error",
                        SUBMIT: [
                            {
                                target: 'loading',
                                cond: (ctx, event) => event.data !== '',
                            },
                            {
                                target: 'error',
                            },
                        ],

                        PREVIOUS: {
                            target: "idle",
                            actions: 'decrementStep',
                            internal: true
                        }
                    },
                },

                step1: {
                    onDone: {
                        target: 'idle',
                    },
                    states: {
                        'new state 1': {
                            invoke: {
                                src: 'startStep',
                                onDone: 'done',
                            },
                        },

                        done: {
                            type: 'final'
                        },
                    },

                    initial: 'new state 1',
                },

                step2: {
                    on: {
                        'Event 1': 'idle',
                    },
                },

                error: {
                    on: {
                        ERROR_HANDLED: 'idle',
                        SUBMIT: {
                            target: 'loading',
                            cond: (ctx, event) => event.data !== '',
                        },
                    },
                },

                loading: {
                    invoke: {
                        id: 'submitStepper',
                        //   src: () => submitForm(),
                        src: 'submitForm',
                        onDone: {
                            target: 'done',
                            actions: assign({ submittedData: (ctx, event) => event.data }),
                        },
                        onError: {
                            target: 'error',
                        },
                    },
                },

                done: {
                    type: 'final',
                }
            },
        },
        {
            actions: {
                incrementStep: assign((context, event) => {
                    console.log('-NEXT INCREMEN', context.step)
                    return {
                        step: context.step + 1,
                    }
                }),
                decrementStep: assign((context, event) => {
                    return {
                        step: context.step - 1,
                    }
                })
            },
            guards: {
                didStep1: (context, event) => {
                    return context.step === 1;
                },
                didStep2: (context, event) => {
                    return context.step === 2;
                },
            },
        },
    );

Expected Result

When onDone is clicked it should transition to next state.

Actual Result

It gets stuck at onDone

image

veeramarni avatar Jan 29 '23 16:01 veeramarni