Open MitkoTschimev opened 6 years ago
You're right, there's a difference in behaviour between using pre-compiled interpolation functions (like when using this plugin) and regular interpolation strings (the ngx-translate default) which leads to this problem.
The way the TranslateDirective
is implemented, it tries to update the view with a translation as soon as the translate
setter is called. This is before the translateParams
setter is called, so the params will be undefined
. This behaviour is questionable, and the reason it crashes with messageformat is this:
// translate.parser.ts (in ngx-translate/core)
private interpolateFunction(fn: Function, params?: any) {
return fn(params);
}
private interpolateString(expr: string, params?: any) {
if (!params) {
return expr;
}
// ...
}
For a string, it is safe to say that without an interpolation parameter, it won't change. (It can lead to rendering a string with non-interpolated parameters, which will be updated to the correct value once translateParams
has been set.) If you have a function however, you need to invoke it to get the resulting string, even if no parameter is needed. If the function does need and tries to accesses the parameter, however, it will naturally throw an error.
For me, the best way to fix this is in the TranslateDirective
. Before trying to get a translation for the key passed to the translate
input, Angular should have had a chance to set the translateParams
input. If the params still do not satisfy what's needed to successfully interpolate then, throwing an error is fine. This would also get rid of unnecessarily rendering incomplete translations.
Another way to fix this would be to catch errors when params
is undefined
in TranslateParser::interpolateFunction
and returning the error message (or some placeholder string) instead, which would be (temporarily) rendered.
@ocombe Do you have any thoughts on this, maybe?
The same issue with the same problem — https://github.com/lephyrus/ngx-translate-messageformat-compiler/issues/28
This does not work even in latest versions of translate plugins.
Angular — 7.2.5 Translate — 11.0.1 Translate Messageformat Compiler — 4.4.0
A workaround is to wrap the TranslateService
:
export class TranslateServiceWrapper extends TranslateService {
getParsedResult (translations: any, key: any, interpolateParams?: any): any {
// here -> setting an empty object as fallback for interpolateParams
return super.getParsedResult(translations, key, interpolateParams ?? {})
}
}
and then override it in the module providers list:
{
provide: TranslateService,
useClass: TranslateServiceWrapper,
},
Note that while the upstream TranslateParser
could still be improved, the default behaviour in this plugin since v7.0.0 is to catch these errors and log them, rather than let them break all translations.
Hello,
i have a problem with following syntax:
-> https://stackblitz.com/edit/angular-tjigun
set translateParams input setter is never triggered
Following format is working:
-> https://stackblitz.com/edit/angular-crnhjq
If I don't use this plugin everything works like expected.
-> https://stackblitz.com/edit/angular-cxxfui
What i can see is that the @input setter of translateParams is not called before the translation process is triggered and than no params are available