Vee-validate: Custom rule: cannot display localized message

Created on 16 Oct 2019  路  5Comments  路  Source: logaretm/vee-validate

Versions

  • vee-validate: 3.0.11
  • vue: 2.6.10

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.

馃悰 bug

All 5 comments

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.

image

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

the94air picture the94air  路  3Comments

jagasan picture jagasan  路  3Comments

Etheryte picture Etheryte  路  3Comments

biapar picture biapar  路  3Comments

MaxMilton picture MaxMilton  路  3Comments