Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

localize does not work at vee-validate@4.7.4 #4164

Closed
2 of 5 tasks
toyokappa opened this issue Feb 27, 2023 · 4 comments
Closed
2 of 5 tasks

localize does not work at vee-validate@4.7.4 #4164

toyokappa opened this issue Feb 27, 2023 · 4 comments
Labels
🐛 bug Unintended behavior

Comments

@toyokappa
Copy link

toyokappa commented Feb 27, 2023

What happened?

I configured like down bellow.

configure({
  generateMessage: localize({
    ja: {
      names: {
        name: "お名前",
        email: "メールアドレス",
      },
    },
  }),
});

This configs work when vee-validate and @vee-validate/i18n version 4.7.3.
image

But, it does not work if I update there versions 4.7.4.
image

Reproduction steps

  1. update there versions 4.7.4.

Version

Vue.js 3.x and vee-validate 4.x

What browsers are you seeing the problem on?

  • Firefox
  • Chrome
  • Safari
  • Microsoft Edge

Relevant log output

there are no error logs.

Demo link

there are no links.

Code of Conduct

@logaretm
Copy link
Owner

logaretm commented Mar 1, 2023

4.7.4 added a fix for a bug where labels were not used in the generated message. Are you adding labels to your fields? those will override the global ones.

If not, could you add an example and I will be happy to take a look. I added a test case in 97d6d75 and it seems to pass fine.

@logaretm logaretm added the 🤔 needs reproduction This issue requires a demo label Mar 1, 2023
@TotomInc
Copy link

@logaretm I'm sorry but it looks like there is a regression somewhere. I actually have the same bug after upgrading to 4.8.1 (but 4.7.4 introduced the regression).

Here's how we are using vee-validate with i18n custom errors & fields name.

Let's start with the generation of i18n errors messages and fields name. We are converting a CSV into an i18n object { [i18nKey: string]: string } with some Vite plugins:

// messages is converted from csv to object, don't mind this
import messages from "../translations.base.csv";

// generate i18n error messages and fields name for all available translations from the csv
const translations = languages.reduce(
  (object, currDecli) => ({
    ...object,
    [currDecli.name]: {
      messages: { required: messages[currDecli.name]["errors.required"] },
      names: { civility: messages[currDecli.name]["register.form.gender"] },
    },
  }),
  {}
);

// translations object have the following format:
// {
//   [i18nKey: string]: {
//     message: { [key: string]: string };
//     fields: { [key: string]: string };
//   };
//  }
configure({ generateMessage: localize(translations) });
// we later set vee-validate locale to the current i18n locale value.
setVeeValidateLocale(i18n.global.locale.value);

This is an output of what the translations object passed to the localize function looks like:

CleanShot 2023-03-14 at 15 04 42@2x

Then, we have created a reusable input component that encapsulate vee-validate using the useField function. I've omitted some lines of code, but the most important should be here:

<template>
  <input
    v-bind="inputAttributes"
    :id="name"
    :value="inputDisplayValue ? inputDisplayValue : field.value.value"
    :name="name"
    @input="onInput(($event.target as HTMLInputElement).value)"
  />
</template>

<script setup lang="ts">
import { useField as useVeeValidateField } from "vee-validate";

const field = useVeeValidateField(props.name, undefined, {
  initialValue: "",
  type: undefined,
  checkedValue: undefined,
  validateOnValueUpdate: false,
  validateOnMount: false,
});
</script>

Then, we have another piece of logic known as a Vue composable/hook. This composable function is used to define the form schema, as well as the rules of each fields inside this form hook.

Please note that this hook is imported into a parent Vue component that contains itself multiple reusable components (so the useForm hook should be able to find inputs useField):

Here's the composable hook that defines the form schema:

import { computed, ref } from "vue";
import { useForm } from "vee-validate";

export const generateVeeValidateForm = () => {
  const initialValues = ref({
    firstname: "",
    lastname: "",
  });

  const schema = computed(() => ({
    // please don't mind latinString, it's a custom rule we have created.
    firstname: "required|latinString",
    lastname: "required|latinString",
  }));

  const form = useForm({ validationSchema: schema, initialValues });

  return { form, schema, initialValue };
};

Finally, we can join all the pieces together in a single RegisterForm.vue component:

<template>
  <form @submit.prevent="">
    <ReusableTextInput
      name="firstname"
      :input-attributes="{
        type: 'text',
        placeholder: $t('register.form.firstnamePlaceholder'),
      }"
    >
      {{ $t("register.form.firstnameLabel") }}
    </ReusableTextInput>

    <ReusableTextInput
      name="lastname"
      :input-attributes="{
        type: 'text',
        placeholder: $t('register.form.lastnamePlaceholder'),
      }"
    >
      {{ $t("register.form.lastnameLabel") }}
    </ReusableTextInput>
  </form>
</template>

<script setup lang="ts">
import { generateVeeValidateForm } from "@/composables/generateVeeValidateForm";

const emit = defineEmits<{
  (e: "formSubmitted", values: RegisterTypes): void;
}>();

const { form } = generateVeeValidateForm();

const handleSubmitForm = form.handleSubmit((formValues) => {
  emit("formSubmitted", formValues);
});
</script>

We thank you a lot for your hard work on this amazing library.

I hope this detailed can help you to pin-point the regression due to recent changes.

@logaretm logaretm reopened this Mar 14, 2023
@logaretm logaretm added 🐛 bug Unintended behavior and removed 🤔 needs reproduction This issue requires a demo labels Mar 14, 2023
@logaretm
Copy link
Owner

logaretm commented Mar 14, 2023

@TotomInc Thanks for your examples, while it didn't show at first it prompted me to test the same test case but with useField and managed to reproduce it. It was because the name is used by default as a label that incorrectly overrode the dictionary ones.

Tagging 4.8.2 with this. LMK if it does fix the issue for you.

@TotomInc
Copy link

Thanks for your quick-fix @logaretm, everything is now working well as intended, I can confirm 4.8.2 resolves the issue. 🔥

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug Unintended behavior
Projects
None yet
Development

No branches or pull requests

3 participants