core icon indicating copy to clipboard operation
core copied to clipboard

Add check for presence of a translation

Open hoeni opened this issue 4 years ago • 9 comments

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

hoeni avatar Sep 23 '19 07:09 hoeni

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 :(

SeeeD avatar Oct 16 '19 13:10 SeeeD

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

chr33z avatar May 08 '20 07:05 chr33z

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;
}

spixy avatar Jul 20 '20 16:07 spixy

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 avatar Oct 08 '20 11:10 M4tiz

@M4tiz there are some errors there and i'm able to reference deep keys with @spixy code

mavriksc avatar Oct 13 '20 16:10 mavriksc

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;
}

aleicher avatar Apr 21 '21 06:04 aleicher

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;
  }

skidrow88 avatar Dec 07 '21 13:12 skidrow88

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"

sdudnic avatar Mar 19 '22 17:03 sdudnic

@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';
}

kraiss avatar Aug 21 '23 12:08 kraiss