Localization of External additional Errors not working as expected

We are using translation functionality in JSON forms as mentioned in i18n - JSON Forms
Translation works for labels and description. But we also have some additional errors which we add we we want to be translated and we are returning error object as –

[
{
instancePath: “/amount”,
message:“* Amount should be less than 20 \r\n* Test second line”,
schemaPath: “”,
params: {},
},
];

Prior to integrating i18 translation we were seeing this message on UI but after i18 instead of message we see “amount.error.custom” , we can add add amount.error.custom single message in our translation but we have multiple error messages which can be returned from out validation logic. Is there any way to add multiple message like amount.error.custom1, amount.error.custom2 or if possible for external validation just show the message which is returned in error object.

Thanks
Abhishek

If you are using i18n then the labels are under full control by your translator code. So if amount.error.custom is shown, then because your translator is returning it.

I would expect that the error message (i.e. * Amount should be less than 20 \r\n* Test second line) is handed over as defaultMessage to the translator. So if you return the defaultMessage back in the translator then the message should show up. If amount.error.custom is shown in the UI then it seems like you are returning the key of the translator, not the defaultMessage.

You mean in additional error object I need to return it as -
const errorObject = [
{
instancePath: “/amount”,
defaultMessage:“* Amount should be less than 20 \r\n* Test second line”,
schemaPath: “”,
params: {},
},
];

but it does not works, or add default message in our translation string file? Also how will it handle different error messages returned based on some condition like “Amount should be greater than 0” and few others for same path.

No, you do not need to modify the error objects themselves.

You indicated that you are using the i18n support of JSON Forms. Therefore you are handing over a translator function to JSON Forms which should look like this:

(key, defaultMessage, context) => string

It seems that for these errors you are returning the key in your translator instead of the defaultMessage.

Yes, I checked translate function, but defaultMessage is coming undefined and key is amount.error.custom, if somehow the additional error message comes in defaultMessage then my issue will get resolved

i18n={{
translate: (key: any, defaultMessage: string) => {
if((key as string).includes(‘amount’))
{
console.log(key, defaultMessage);
}
return t(key, { ns: props.widgetType });
}
}}

See this “Note” in the docs:

If the defaultMessage is undefined , you should also return undefined if there is no translation for the given key. Returning an empty string (or something similar) instead may result in undesired behavior. JSON Forms will use undefined when the message could be skipped or another more generic key could be tried.

So please return undefined if you don’t have a translation there. Regarding errors, JSON Forms will try many different keys for the same error. All the first ones will have undefined as the defaultMessage. Only the last one will have the error.message string as the defaultMessage. This process is also described in the docs.

See especially the last part:

Default AJV error message
If none of the above apply, the message provided by the AJV error object will be used.

Thank you!! that helped, on returning undefined I got error.undefined shown on UI but after adding keyword in error object and returning undefined next key which came was error.amount.custom2 which solved my issue eg

const errorObject = [
{
instancePath: “/amount”,
keyword: “amount.custom2”,
message:“* Amount should be less than 20 \r\n* Test second line”,
schemaPath: “”,
params: {},
},
];

1 Like