Problems with translations with Vue, Yup and i18n
I have a Vue.js App (with Vite) where I use Vee-validate with Yup for form validation and use i18n for message translation. However, the custom errors in the schema do not update in real time when the user sets $i18n.locale='xx'
Schema:
import { useI18n } from "vue-i18n"
const {t} = useI18n()
const schema = yup.object().shape({
username: yup
.string()
.required(t("field_required"))
.email(t("field_error_email")),
password: yup.string().required(t("field_required"))
})
Messages printed directly to the template with $t("message")
work normally.
Versions:
"dependencies": {
"vee-validate": "^4.5.11",
"vue": "^3.2.33",
"vue-i18n": "^9.1.9",
"yup": "^0.32.11"
}
1 answer
-
answered 2022-04-29 19:55
Estus Flask
t("field_required")
is passed as a string during component setup, it cannot be reactive. In order to be reactive, it should be evaluated at the time when a message really needs to be accessed, i.e. during schema validation. It's expected thatrequired
, etc schema methods accept a function to evaluate a message lazily for this purpose, and they actually do.It should be:
const schema = yup.object().shape({ username: yup .string() .required(() => t("field_required")) ...
do you know?
how many words do you know
See also questions close to this topic
-
how to change prettier format for react native
my code formatting prettier didn't works well for react native, i don't understand where to config it but it works well with flutter
from this code
import { View, Text } from 'react-native' import React from 'react' export default function App() { return ( <View> <Text>Apps</Text> </View> ) }
it's formatted to this
import { View, Text } from 'react-native' import React from 'react' export default function App() { return ( < View > < Text > Apps < /Text> < /View> ) }
-
MarkLogic server-side JavaScript and XQuery
I am just starting using NoSQL MarkLogic DB and trying to choose for me the best query language to learn and use in future. On server side MarkLogic provides the possibility to use JavaScript API or XQuery API.
I want to receive an advice. Which language is better to concentrate on and learn? JavaScript or XQuery?
- Popover in chrome extension using js
-
How can I get toast-ui editor content?
I am a student studying. I think I'm doing it conceptually wrong.
I'm trying to use vue3 and type script And I'm going to use toast-ui editor.
I get some errors.
- refEditor.value.invoke is not a function
How can I get toast-ui editor content?
this is my code
<template> <div class="markup-tables flex"> <va-card :title="$t('tables.stripedHoverable')"> <va-card-content> <div id="refEditor" ref="refEditor"></div> <br /> <div class="row justify--end paginationButtons-left"> <va-button class="mr-2 mb-2">List</va-button> </div> <div class="row justify--end paginationButtons-right"> <va-button class="mr-2 mb-2" @click="getHTML">Save</va-button> </div> </va-card-content> </va-card> </div> </template> <script lang="ts"> import '@toast-ui/editor/dist/toastui-editor.css' import Editor from '@toast-ui/editor' import { defineComponent, onMounted, ref } from 'vue' import data from '@/data/tables/markup-table/data.json' export default defineComponent({ name: 'BoardWrite', setup() { const refEditor = ref(null) const getHTML = () => { console.log('getHTML test') let html = refEditor.value.invoke('getHtml') console.log(html) // ERROR } onMounted(() => { const editor = new Editor({ el: refEditor.value, height: '700px', initialEditType: 'markdown', previewStyle: 'vertical', }) editor.getMarkdown() }) return { getHTML, refEditor, } }, }) </script>
-
Deploy VueJS + API app to Azure Static Web App with Gitlab doesn't create functions
I've started creating a small application that will use VueJS as a frontend with Azure Functions as the backend. I was looking at using Azure Static Web Apps to host both components for the application and Gitlab to store / deploy the app.
Everything but the creation of the Azure functions works. Following https://docs.microsoft.com/en-us/azure/static-web-apps/gitlab?tabs=vue
The output from the deploy step, listed below is:
App Directory Location: '/builds/*/valhalla/valhalla-client/dist/spa' was found. Api Directory Location: '/builds/*/valhalla/valhalla-api/dist' was found. Looking for event info Could not get event info. Proceeding Starting to build app with Oryx Azure Static Web Apps utilizes Oryx to build both static applications and Azure Functions. You can find more details on Oryx here: https://github.com/microsoft/Oryx ---Oryx build logs--- Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx You can report issues at https://github.com/Microsoft/Oryx/issues Oryx Version: 0.2.20220131.3, Commit: ec344c058843461525ff03b46031553b6e15a47a, ReleaseTagName: 20220131.3 Build Operation ID: |qAffRWArEg8=.deee9498_ Repository Commit : 7cdd5b61f956e6cb8459b13a42af363c4440a97b Detecting platforms... Could not detect any platform in the source directory. Error: Could not detect the language from repo. ---End of Oryx build logs--- Oryx was unable to determine the build steps. Continuing assuming the assets in this folder are already built. If this is an unexpected behavior please contact support. Finished building app with Oryx Starting to build function app with Oryx ---Oryx build logs--- Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx You can report issues at https://github.com/Microsoft/Oryx/issues Oryx Version: 0.2.20220131.3, Commit: ec344c058843461525ff03b46031553b6e15a47a, ReleaseTagName: 20220131.3 Build Operation ID: |NGXLP5bVBRk=.705477f6_ Repository Commit : 7cdd5b61f956e6cb8459b13a42af363c4440a97b Detecting platforms... Could not detect any platform in the source directory. Error: Could not detect the language from repo. ---End of Oryx build logs--- Oryx was unable to determine the build steps. Continuing assuming the assets in this folder are already built. If this is an unexpected behavior please contact support. [WARNING] The function language could not be detected. The language will be defaulted to node. Function Runtime Information. OS: linux, Functions Runtime: ~3, node version: 12 Finished building function app with Oryx Zipping Api Artifacts Done Zipping Api Artifacts Zipping App Artifacts Done Zipping App Artifacts Uploading build artifacts. Finished Upload. Polling on deployment. Status: InProgress. Time: 0.1762737(s) Status: InProgress. Time: 15.3950401(s) Status: Succeeded. Time: 30.5043965(s) Deployment Complete :) Visit your site at: https://polite-pebble-0dc00000f.1.azurestaticapps.net Thanks for using Azure Static Web Apps! Exiting Cleaning up project directory and file based variables 00:00 Job succeeded
The deploy step appears to have succeeded, and the frontend is deployed, but there are no Azure Functions showing up in this Static Web App. Is something missed here? So far, the Azure Functions I have are the boiler-plate from instantiating a new Azure Function folder.
image: node:latest variables: API_TOKEN: $DEPLOYMENT_TOKEN APP_PATH: '$CI_PROJECT_DIR/valhalla-client/dist/spa' API_PATH: '$CI_PROJECT_DIR/valhalla-api/dist' stages: - install_api - build_api - install_client - build_client - deploy install_api: stage: install_api script: - cd valhalla-api - npm ci artifacts: paths: - valhalla-api/node_modules/ cache: key: node paths: - valhalla-api/node_modules/ only: - master install_client: stage: install_client script: - cd valhalla-client - npm ci artifacts: paths: - valhalla-client/node_modules/ cache: key: node paths: - valhalla-client/node_modules/ only: - master build_api: stage: build_api dependencies: - install_api script: - cd valhalla-api - npm install -g azure-functions-core-tools@3 --unsafe-perm true - npm run build artifacts: paths: - valhalla-api/dist cache: key: build_api paths: - valhalla-api/dist only: - master needs: - job: install_api artifacts: true optional: true build_client: stage: build_client dependencies: - install_client script: - cd valhalla-client - npm i -g @quasar/cli - quasar build artifacts: paths: - valhalla-client/dist/spa cache: key: build_client paths: - valhalla-client/dist/spa only: - master needs: - job: install_client artifacts: true optional: true deploy: stage: deploy dependencies: - build_api - build_client image: registry.gitlab.com/static-web-apps/azure-static-web-apps-deploy script: - echo "App deployed successfully." only: - master
-
How to global import a stylus file in vite
Now I'm try use
vite
to create avue
app. But have trouble to global import astylus
file invite.config.js
.I try the code from vite docs.
export default defineConfig({ css: { preprocessorOptions: { styl: { additionalData: `@import "./src/assets/styles/common.styl"` } } } })
But it's completely not work.
I got a solution to set global style from github.
export default defineConfig({ css: { preprocessorOptions: { stylus: { globals: { '$highlight-color': 'red' } } } } })
It's works fine, But how to import a styl file globaly? I tried to add 'additionalData' to the workable config. However I got bunch of errors: 'failed to locate file'. It seems like try to import the file in every .vue file, but has trouble to locate the file.
css: { preprocessorOptions: { stylus: { additionalData: `@import "./src/assets/styles/common.styl";`, globals: { '$color-g1': '#F3F4FC', '$color-white': '#FFFFFF', } } } }
Have any idea about this?
-
Form level validation (no field level) with formik validation schema for combination of fields
Let's assume we have to use the form with username and nickname field. And the max count of each field is 250 letters and it is not mandatory required. But one of these fields should be exists. The way it to add validation for each field by using Yup as below
const SignupSchema = Yup.object().shape({ userName: Yup.string() .max(50, 'Too Long!') .test('Required', 'one of these fields required', function(value){ return this.parent.nickName || value; }), nickName: Yup.string() .max(50, 'Too Long!') .test('Required', 'one of these fields required', function(value){ return this.parent.userName || value; }), });
But this is for field level validation, and I don't want to show error message for each field but show the "one of these items should be required" error message at the top or bottom of the whole form. I am not sure how to get form level error message.
-
Formik Error: Objects are not valid as a React child (found: object with keys {})
I am using Formik to handle forms in a next Js project but I keep getting this weird error:
Warning: Invalid field name. Either pass `useField` a string or an object containing a `name` key. Error: Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead.
Nothing I have tried is working. This is not my first time of using Formik which makes this error somewhat weird. I have checked all my formik input components and can't seem to find any issues with my return statements.
Here is my
<InputField />
Component using Formik:import { ErrorMessage, useField } from 'formik'; import { HiExclamationCircle } from 'react-icons/hi'; import classNames from 'classnames'; import PropTypes from 'prop-types'; InputFieldOverflow.propTypes = { label: PropTypes.string, placeholder: PropTypes.string, name: PropTypes.string.isRequired, variant: PropTypes.string, size: PropTypes.string, }; function InputField({ label, name, placeholder, variant, size, ...props }) { const [ field, meta ] = useField(props); return ( <> {label && ( <label htmlFor={name} className="block sm:text-sm text-xs font-normal text-theblack mb-[5px]"> {label} </label> )} <div className="relative"> <input {...field} {...props} type="text" id={name} className={classNames( "block w-full rounded-lg shadow-xs sm:text-sm text-xs placeholder-body", { 'focus:ring-error border-error focus:border-error': meta.touched && meta.error, 'focus:ring-success border-gray-stroke focus:border-success' : !meta.touched && !meta.error, 'bg-white ': variant === 'primary', 'bg-input text-body': variant === 'secondary', 'sm:h-[60px] h-[50px]': size === 'big', 'sm:h-[50px] h-[50px]': size === 'small', 'h-[180px]': size === 'textArea', } )} placeholder={placeholder} aria-describedby={name} /> {meta.touched && meta.error && ( <div className="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none"> <HiExclamationCircle className="text-xl text-error" /> </div> )} </div> <ErrorMessage component="p" name={field.name} className="text-xs text-error mt-[5px]" /> </> ); } export default InputField;
Here is how I use it a page
import InputField from '@/components/Fields/InputField'; import Button from '@/components/Button/Button'; import { Formik, Form } from 'formik'; import * as Yup from 'yup'; import { withSettingsNavLayout } from '@/layouts/dashboard/settings-nav'; function MyAccount() { const formValidationSchema = Yup.object().shape({ fullName: Yup.string().min(8, "Full name must be at least 8 characters long").max(30, "Full name must not be more than 30 characters long").required("Full name is required"), userName: Yup.string().min(5, "Username must be at least 5 characters long").max(15, "Username must not be more than 15 characters long").required("username is required"), }); const formInitialValues = { fullName: 'John Doe', userName: 'johndoe2022', } return ( <> <div className="sm:mt-[34px] mt-[25px] md:ml-[30px] md:mr-[81px] mx-[10px] w-full sm:w-[610px]"> <Formik initialValues={formInitialValues} validationSchema={formValidationSchema} > {() => ( <Form> <InputField name="fullName" label="Full Name" variant="secondary" size="small" /> <div className="mt-[30px]"> <InputField name="userName" label="Username" variant="secondary" size="small" /> </div> <Button type="submit" variant="secondary" > Submit </Button> </Form> )} </Formik> </div> </> ); } export default withSettingsNavLayout(MyAccount);
What is causing this weird error and how can I fix it. Thank you very much in advance.
-
yup.js object validation, allow any key but values must be string or string array
I am using https://github.com/jquense/yup#yup
I want to have an object validation schema for:
subObjectField: { [thisKeyCanBeAnyString]: string | string[] // allow string or array of strings }
I cannot find an example or a starting point to achieve this, any ideas?
-
How to rewrite type defination of third party library in vue project created by create-vue
I have a vue project using
cesium
library, following the update of cesium, some errors occur.My code:
camera.setView({ destination, orientation: { heading, pitch } })
Error:
Type '{ heading: number; pitch: number; }' is not assignable to type 'HeadingPitchRollValues | DirectionUp | undefined'. Property 'roll' is missing in type '{ heading: number; pitch: number; }' but required in type 'HeadingPitchRollValues'.
The function signature:
setView(options: { destination?: Cartesian3 | Rectangle; orientation?: HeadingPitchRollValues | DirectionUp; endTransform?: Matrix4; convert?: boolean; }): void; export type HeadingPitchRollValues = { heading: number; pitch: number; roll: number; };
But in fact the function handles the absence of the roll attribute:
// Part of javascript source code, handles default value // of heading,pitch and roll scratchHpr.heading = defaultValue(orientation.heading, 0.0); scratchHpr.pitch = defaultValue(orientation.pitch, -CesiumMath.PI_OVER_TWO); scratchHpr.roll = defaultValue(orientation.roll, 0.0);
So the type defination should be:
setView(options: { destination?: Cartesian3 | Rectangle; orientation?: Partial<HeadingPitchRollValues> | DirectionUp; endTransform?: Matrix4; convert?: boolean; }): void;
I want to rewrite this type in my vue project without using
patch-package
, how should I do?My repo: https://github.com/Gu-Miao/learn-cesium
SOME UPDATE
cesium library type defination structure:
declare module 'cesium' { // ...some classes and functions export class Camera { // ...some properties setView(options: { destination?: Cartesian3 | Rectangle orientation?: HeadingPitchRollValues | DirectionUp endTransform?: Matrix4 convert?: boolean }): void } }
And there are too many classes and functions so that the file size is about 2MB. What I want is rewrite
setView()
function's type and keep other work as normal. -
vitest test await async completion of onMounted callback in vue3 component
I'm playing around with Vitest and want to wait for the completion of a couple mocked fetches in the onMounted lifecycle hook in my component:
My test:
import { mount } from '@vue/test-utils'; import HelloWorld from './HelloWorld.vue'; import { mockGet } from 'vi-fetch'; import 'vi-fetch/setup'; mockGet('api/welcome-message').willResolve('Welcome message from vitest'); mockGet('api/players').willResolve(['Mario', 'Luigi']); test('the players have been rendered', async () => { const wrapper = mount(HelloWorld); const lastPlayer = await wrapper.findAll('.player'); expect(lastPlayer).toHaveLength(2); });
My component script:
<script setup lang="ts"> import { onMounted, ref } from 'vue'; const apiMessage = ref(''); const players = ref<string[]>([]); onMounted(async () => { const fetchMessage = fetch('api/welcome-message') .then((res) => res.text()) .then((message: string) => (apiMessage.value = message)); const fetchPlayers = fetch('api/players') .then((res) => res.json()) .then((playersRes: string[]) => (players.value = playersRes)); }); </script>
The test fails because, I assume, the code running in onMounted doesn't have time to complete before the test looks for all
.player
<li>
elements (rendered with a v-for) off of theplayers
ref. How can I ask vitest to wait for the responses from each of these fetches before calling the test a failure.Thanks.
-
Vue i18n - can not dynamically change locale
I have a small vue app where I want to implement the vue-i18n plug to make my app multilingual. I have installed the vue-i18n plugin from the vue cli. I have two locales and everything works as expected - whenever I manually change the locale from the.env file to the desired language, the language in the app also changes.However, whenever I try to change it with a button on the frontend I fail to do so.
This is what I have in my i18n.js file:
import { createI18n } from 'vue-i18n' function loadLocaleMessages() { const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i); const messages = {}; locales.keys().forEach(key => { const matched = key.match(/([A-Za-z0-9-_]+)\./i); if (matched && matched.length > 1) { const locale = matched[1]; messages[locale] = locales(key); } }) return messages; } export default createI18n({ legacy: false, locale: process.env.VUE_APP_I18N_LOCALE || 'en', fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en', messages: loadLocaleMessages() })
This is in .env file:
VUE_APP_I18N_LOCALE=en VUE_APP_I18N_FALLBACK_LOCALE=en
This is code from a tutorial I saw and they access the locale by this.$i18n.locale, however, this does not work for me, this is how I try to implement it:
<template> <div class="hello"> <h1>Hello World</h1> <h2>{{ t("hello") }}</h2> <h2>{{ t("message") }}</h2> <button @click="SetLocale('en')">EN</button> <button @click="SetLocale('nl')">NL</button> </div> </template> <script> import { useI18n } from "vue-i18n"; export default { name: "HelloWorld", setup() { const { t } = useI18n({ inheritLocale: true, useScope: "local", }); // Something todo .. return { t }; }, methods: { SetLocale(locale) { console.log(locale); this.$i18n.locale = locale; }, }, }; </script> <i18n> { "en": { "hello": "Hello i18n in English! (from component)", }, "nl": { "hello": "Hello i18n in Dutch! (from component)", } } </i18n>
The error that I get when I click the button is:
[Vue warn]: Unhandled error during execution of native event handler
Uncaught TypeError: Cannot set properties of undefined (setting 'locale')
I have tried some other solutions like i18n.locale and this.$root.$i18n.locale but they dont seem to work either.
In addition when I try to access the
{{ t("message") }}
from which message comes from a JSON file from locales folder I get those warnings:[intlify] Not found 'message' key in 'nl' locale messages.
[intlify] Fall back to translate 'message' key with 'en' locale
[intlify] Not found 'message' key in 'en' locale messages.
[intlify] Fall back to translate 'message' key with 'nl' locale
My question is, where am I doing something wrong and is there a way to get rid of the warnings that I have when I try to access the JSON files from the locales folder?
-
Problem in accessing i18n.locales in vue components and changing its value dynamically
I have a small vue app where I want to implement the vue-i18n plug to make my app multilingual. I have installed the vue-i18n plugin from the vue cli. I have two locales and everything works as expected - whenever I manually change the locale from the.env file to the desired language, the language in the app also changes.However, whenever I try to change it with a button on the frontend I fail to do so.
This is what I have in my i18n.js file:
import { createI18n } from 'vue-i18n' function loadLocaleMessages() { const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i) const messages = {} locales.keys().forEach(key => { const matched = key.match(/([A-Za-z0-9-_]+)\./i) if (matched && matched.length > 1) { const locale = matched[1] messages[locale] = locales(key) } }) return messages } export default createI18n({ legacy: false, locale: process.env.VUE_APP_I18N_LOCALE || 'en', fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en', messages: loadLocaleMessages() })
This is in .env file:
VUE_APP_I18N_LOCALE=en VUE_APP_I18N_FALLBACK_LOCALE=en
This is code from a tutorial I saw and they access the locale by
this.$i18n.locale
, however this does not work for me, this is how I try to implement it:<template> <div class="hello"> <h1>Hello World</h1> <h2>{{ t("hello") }}</h2> <h2>{{ t("message") }}</h2> <button @click="SetLocale('en')">EN</button> <button @click="SetLocale('nl')">NL</button> </div> </template> <script> import { useI18n } from "vue-i18n"; export default { name: "HelloWorld", setup() { const { t } = useI18n({ inheritLocale: true, useScope: "local", }); // Something todo .. return { t }; }, methods: { SetLocale(locale) { console.log(locale); this.$i18n.locale = locale; }, }, }; </script> <i18n> { "en": { "hello": "Hello i18n in English! (from component)" }, "nl": { "hello": "Hello i18n in Dutch! (from component)" } } </i18n>
The error that I get when is:
[Vue warn]: Unhandled error during execution of native event handler
Uncaught TypeError: Cannot set properties of undefined (setting 'locale')
I have tried some other solutions like
i18n.locale
andthis.$root.$i18n.locale
but they dont seem to work either.In addition when I try to access the
<h2>{{ t("message") }}</h2>
from whichmessage
comes from a JSON file from locales folder I get those warnings:[intlify] Not found 'message' key in 'nl' locale messages.
[intlify] Fall back to translate 'message' key with 'en' locale
[intlify] Not found 'message' key in 'en' locale messages.
[intlify] Fall back to translate 'message' key with 'nl' locale
My question is, where am I doing something wrong and is there a way to get rid of the warnings that I have when I try to access the JSON files from the
locales
folder>