laravel / precognition

Anticipate the outcome of a future HTTP request.
https://laravel.com/docs/precognition
MIT License
130 stars 31 forks source link

Async validate() handlers not called when form does not need validation #99

Open stefanfisk opened 4 days ago

stefanfisk commented 4 days ago

Laravel Precognition Plugin Version

0.5.7

Laravel Version

10.43

Plugin

Alpine

Description

The async validate() handlers are not called if the request is equal to the previous request.

If I understand everything correctly the root cause is that onBeforeValidation() short circuits the request.

As a workaround onBeforeValidation: () => true can be added to the validate() config.

Steps To Reproduce

Call the following code twice. The second time it will not output anything.

 this.form.validate({
    onSuccess: (response) => {
        console.log('onSuccess', response);
    },
    onValidationError: (response, axiosError) => {
        console.log('onValidationError', response, axiosError);
    },
});
timacdonald commented 3 days ago

@stefanfisk, this is by design.

Could you outline the exact issue you are facing in your application?

stefanfisk commented 1 day ago

@timacdonald I have two use cases where this has caused me issues, both for when the user submits the form.

The first use case is to focus the first input with an error. So when the user submits the form it is fully validated and then the first input with an error is focused. If the user tries to submit a second time without actually editing the form the same thing should happen again.

The second use case is a form where I want to perform a file upload to S3 before actually submitting the form. So my idea was to:

  1. Validate all fields
  2. If there are no errors, upload the files to S3
  3. Submit the form

The workaround with onBeforeValidation is fine for me since the number of extra requests should be low. But I was very confused when validate() sometimes simply did nothing and I could find no mention of this behavior in the changelog or pull request.

Unless I am mistaken your example with the Next button in https://github.com/laravel/precognition/pull/69 will also result in the button not actually doing anything on consecutive clicks. So if the user does not notice the first message about the form having validation errors the button is just dead until the user edits the form or does something else that triggers a validation so that the previous request no longer matches the next request.