xstate icon indicating copy to clipboard operation
xstate copied to clipboard

Bug: [Xstate/vue] - mapping v-model in an input field to context data causes delay in guard validation

Open mayashavin opened this issue 11 months ago • 3 comments

XState version

XState version 5

Description

I have a form machine that use state machine with the following guard to check if you can move to the next phase:

const multistepMachineConfigs = setup({
  id: 'multistep',
  guards: {
    isFormValid: ({ context }) => {
      const { name, email, password } = context.formData
      return name && email && password
    },
  },
})l

export const multistepMachine = multistepMachineConfigs.createMachine({
  initial: 'name',
  context: {
    formData: {
      name: '',
      email: '',
      password: '',
    },
  },
  states: {
    //....
    password: {
      on: {
        SUBMIT: {
          target: 'submit',
          guard: 'isFormValid',
        },
        PREV: 'email',
      },
    },
    submit: {
      //....
    },
  },
})

In the component, I map the context.formData.password to the input field using v-model directly

<input
        v-model="snapshot.context.formData.password"
        placeholder="Password"
        type="password"
        class="w-full p-2 my-2 border border-gray-300 rounded-md"
      />

Expected result

Expect the Submit button to be enabled the moment the user fills in the input field.

Actual result

Only when you go back one step before and move forward to the current step, the Submit button will be enabled. Looks like the updating cycle is a bit slower.

https://github.com/user-attachments/assets/fd771430-cbf8-4f93-a128-c6fd0a1abacb

Reproduction

https://github.com/mayashavin/multi-step-form-xstate-2025

Additional context

Switching to use an event, like UPDATE and map it to @input event will work.

mayashavin avatar Feb 05 '25 07:02 mayashavin

I can't repro the problem. I think you meant to report a repro using MutiformMachineView.vue (and not MutiformView.vue). It took me a moment to figure that out. But even with that used - the Submit button switches to the enabled state as soon as I type a single character into the password's input

Andarist avatar Feb 05 '25 09:02 Andarist

@Andarist it is because I switched to use @input inside MultiformMachineView.vue. But if you remove that and use v-model="state.context.formData.password", the issue will happen.

Sorry I should be more clear about the repo, it was a demo so I have to use the workaround to make it work.

mayashavin avatar Feb 05 '25 10:02 mayashavin

@Andarist the branch with that issue - https://github.com/mayashavin/multi-step-form-xstate-2025/tree/v-model-sync-issue

mayashavin avatar Feb 05 '25 10:02 mayashavin