victorgarciaesgi / regle

✅ Typescript first model-based form validation library for Vue 3
https://regle.vercel.app
MIT License
11 stars 1 forks source link

Rule message is _sometimes_ reactive, reactivity broken #25

Closed martinszeltins closed 7 hours ago

martinszeltins commented 8 hours ago

I have a rule that shows an error message and uses a ref inside the message. Sometimes it is reactive and other times it is not. Something is broken.

So I have a field weight with a rule like this:

const minWeightRule = () => {
    return withMessage(
        withParams(value => {
            return Number(value) >= someNumber.value
                && someCondition.value === false
        }, [someCondition, someNumber]),
        t('no_good', { name: someNumber.value })
    )
}

If it is invalid it shows a message: "No Good. someNumber: 4"

But if I change the value of someNumber ref, then the message does not change. If I fill out the form again and validate again, then it changes (see screencast). It's really strange.

Reproduction: https://stackblitz.com/~/github.com/martinszeltins/regle-test-12

Screencast:

As you can see here, the value stays 4 until I validate, change the form values etc. then it changes to 7....

https://github.com/user-attachments/assets/85c02ec1-779e-452f-8ecf-a60b21ef3c9b

victorgarciaesgi commented 7 hours ago

Here it's because your message is static, so evaluated only when computed is triggered

you need to return a function for your message

 const minWeightRule = () => withMessage(
            withParams(value => {
                return Number(value) >= someNumber.value
                    && someCondition.value === false
            }, [someCondition, someNumber]),
            () => t('no_good', { name: someNumber.value })
        )
martinszeltins commented 7 hours ago

Here it's because your message is static, so evaluated only when computed is triggered

you need to return a function for your message

 const minWeightRule = () => withMessage(
            withParams(value => {
                return Number(value) >= someNumber.value
                    && someCondition.value === false
            }, [someCondition, someNumber]),
            () => t('no_good', { name: someNumber.value })
        )

Ah! Phew! Crisis averted. Thanks! 🫡