core
core copied to clipboard
Add check for presence of a translation
Current behavior
There is no way to be certain about the existence of a translation for a specific key. The best thing I can do is checking if the translation is the same as the given key:
if (this.translate.instant(myKey) === myKey) { ... }
However, besides not being pretty, this cannot detect the case when the translation really is the same as the key.
Expected behavior
It would be nice to have a safe and concise test for the presence of a translation.
How do you think that we should implement this?
if(this.translate.hasTranslation(key)) { ... }
Nice bonus: Give it an optional argument for testing another language instead of the current:
hasTranslation(translationKey: string, language?: string): boolean
Another nice feature would be not triggering the "MissingTranslationsHandler" when calling this method you suggested. I'm using it like you above and I filter some translation-terms from my "MissingTranslationsHandler". That's some kind of dirty for me :(
Hey, I wrote a Visual Studio Code Extension that shows translations inline in the codebase. Maybe this can help during development as you can see if a certain identifier has a corresponding translation in a .json file.
https://marketplace.visualstudio.com/items?itemName=chr33z.lingua-vscode
You can easily check with:
import { TranslateService } from '@ngx-translate/core';
constructor(private translateService: TranslateService) { }
public hasTranslation(translationKey: string, language?: string): boolean {
const translations = this.translateService.translations[language || this.translateService.currentLang];
return translations && translations[translationKey] !== undefined;
}
A slightly improved version of @spixy where you can reference deep keys via dot notation eg. VERY.DEEP.TRANSLATION
import { TranslateService } from '@ngx-translate/core';
constructor(private translateService: TranslateService) { }
public hasTranslation(translationKey: string, language?: string): boolean {
const translation: object | string = this.translateService.translations[language || this.translateService.currentLang];
const value = key
.split('.')
.reduce((t, k) => t[k] || {}, translation || {});
return value !== undefined;
}
@M4tiz there are some errors there and i'm able to reference deep keys with @spixy code
this version of @M4tiz code snippet worked for me:
import { TranslateService } from '@ngx-translate/core';
constructor(private translateService: TranslateService) { }
public hasTranslation(translationKey: string, language?: string): boolean {
const translation: object | string = this.translateService.translations[language || this.translate.currentLang];
const value = translationKey
.split('.')
.reduce((translation, k) => translation && translation[k], translation);
return value !== undefined;
}
Another way to do it:
import { TranslateService } from '@ngx-translate/core';
constructor(private translate: TranslateService) { }
public hasTranslation(translationKey: string): boolean {
let isTranslated: boolean = true;
if (this.translate.instant(translationKey) == translationKey){
isTranslated = false;
}
return isTranslated;
}
Another way to do it:
import { TranslateService } from '@ngx-translate/core'; constructor(private translate: TranslateService) { } public hasTranslation(translationKey: string): boolean { let isTranslated: boolean = true; if (this.translate.instant(translationKey) == translationKey){ isTranslated = false; } return isTranslated; }
does not take into consideration the case when the translation is actually the key, like "OK": "OK"
@M4tiz Snippet didn't work for me because value
can be an empty object after the reduction. I fixed it like this, if this can help someone
import { TranslateService } from '@ngx-translate/core';
constructor(private translateService: TranslateService) { }
public hasTranslation(translationKey: string, language?: string): boolean {
const translation: object | string = this.translateService.translations[language || this.translateService.currentLang];
const value = key
.split('.')
.reduce((t, k) => t[k] || {}, translation || {});
return typeof value === 'string';
}