Versions
Describe the bug
I cannot seem to add localized messages via the localize() function for custom rules. Instead it will display the generic input is not valid message. I tried everyway of registering the language message, but there just is no way to get the rule return the localized message (not using any other l18n solution, just the internal vee-validate localization).
To reproduce
This is my registration of the custom rule, which does not define a static message (!) (note i also tried all forms of the localize() function (and i suggest to review the documentation, since it is, at least to me, still not clear how this function operates with each input).
import Vue from 'vue';
import _ from 'lodash';
import { ValidationProvider, ValidationObserver, localize, extend } from 'vee-validate/dist/vee-validate.full';
import rules from './rules';
import de from 'vee-validate/dist/locale/de.json';
import deInternal from './lang/de.json';
import enInternal from './lang/en.json';
extend('required_if_empty', rules.required_if_empty);
var mergedDE = _.merge({}, de, deInternal);
// Set vee-validate language
localize({
en: enInternal,
de: mergedDE,
});
localize('de');
Vue.component('ValidationObserver', ValidationObserver);
Vue.component('ValidationProvider', ValidationProvider);
Expected behavior
I expect the rule to use the current localized message.
Thank you.
PS: Referencing #2318 here, since it would also lead to the same error, i suppose.
The sourse of the bug is in the init logic: for vee-validate.full.js
2615: // Install locale
2616: localize('en', en);
After this initial call, updateRules() method will never be called again as INSTALLED flag is already set to true:
var INSTALLED = false;
function updateRules() {
if (INSTALLED) {
return;
}
RuleContainer.iterate(function (name, schema) {
var _a, _b;
if (schema.message && !DICTIONARY.hasRule(name)) {
DICTIONARY.merge((_a = {},
_a[DICTIONARY.locale] = {
messages: (_b = {},
_b[name] = schema.message,
_b)
},
_a));
}
extend(name, {
message: function (field, values) {
return DICTIONARY.resolve(field, name, values || {});
}
});
});
INSTALLED = true;
}
function localize(locale, dictionary) {
var _a;
if (!DICTIONARY) {
DICTIONARY = new Dictionary('en', {});
}
if (typeof locale === 'string') {
DICTIONARY.locale = locale;
if (dictionary) {
DICTIONARY.merge((_a = {}, _a[locale] = dictionary, _a));
}
updateRules();
return;
}
DICTIONARY.merge(locale);
updateRules();
}
To overcome i used this code to explicitly rewrite translation string for each rule:
Object.keys(newLocaleMessages).forEach(
ruleName => {
extend(ruleName, {
message: newLocaleMessages[ruleName]
});
}
);
@logaretm Are you going to take a look at this?
Also, it would be nice, if we could load localizations once and they are picked up by rules that are extend()ed later on somewhere in the app.
As far as I understand, currently l10n messages are only applied to rules that are already registered. But due to this bug it's not possible to re-invoke localize() each time a rule is added.
Thanks :+1:
Hi @logaretm ,
I noticed today an issue following this fix. The issue is when I use the configure method with defaultMessage property and then call localize for the first time.
In this case, the defaultMessage method is replaced by the one you added when you create the DICTIONARY.

Is there any way to keep the defaultMessage method if already configured ?
The only workaround I found is to call localize method the first time before the configure method.
Thanks for your feedback,
Nicolas