I'm submitting a ... (check one with "x")
[ ] bug report => check the FAQ and search github for a similar issue or PR before submitting
[ ] support request => check the FAQ and search github for a similar issue before submitting
[x] feature request
Current behavior
"HELLO": ""
shows blank i the view
Expected/desired behavior
I expect it to show HELLO
this way translators can see which strings they need to translate
Reproduction of the problem
If the current behavior is a bug or you can illustrate your feature request better with an example, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar. You can use this template as a starting point: http://plnkr.co/edit/tpl:WccVZSBM0rUgq2sXSUbe
What is the expected behavior?
What is the motivation / use case for changing the behavior?
Please tell us about your environment:
"@ngx-translate/core": "^7.1.0",
"@ngx-translate/http-loader": "^1.0.1",
Angular version: 2.x.x
Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
A workaround for this is to exclude default language from extraction, i.e.:
export class AppComponent {
constructor(translate: TranslateService) {
translate.setDefaultLang('none');
translate.use('pl');
}
}
and in package.json:
"extract": "ngx-translate-extract --input ./src --output ./src/assets/i18n/{en,pl,de,fr}.json --clean --sort --format namespaced-json"
This way you will see untranslated strings from source instead of empty replacements.
I don't think this very special use case should result in the default being changed. An empty string is a valid value and should not be treated the same as null (which is the correct value for "not translated").
You could write a parser plugin which replaces empty strings with null/undefined, or something like that.
I agree with @gemal this is completely killing the fallback feature!
I you don't want it as standard feature ok, but anyway we should have the choice to filter out empty string.
You can use this modified loader code. It removes empty strings from the files:
import {TranslateLoader} from '@ngx-translate/core';
import {HttpClient} from "@angular/common/http";
import 'rxjs/add/operator/map';
export class PruningTranslationLoader implements TranslateLoader {
constructor(private http: HttpClient, private prefix: string = '/assets/i18n/', private suffix: string = '.json') {
}
public getTranslation(lang: string): any {
return this.http.get(`${this.prefix}${lang}${this.suffix}`)
.map((res: Object) => this.process(res));
}
private process(object: any) {
const newObject = {};
for (const key in object) {
if (object.hasOwnProperty(key)) {
if (typeof object[key] === 'object') {
newObject[key] = this.process(object[key]);
}
else if ((typeof object[key] === 'string') && (object[key] === '')) {
// do not copy empty strings
}
else {
newObject[key] = object[key];
}
}
}
return newObject;
}
}
@CodeAndWeb
I added the same code provided above and then added
providers: [
{
provide: TranslateLoader,
useClass: PruningTranslationLoader,
},
],
got this error
Error: Can't resolve all parameters for PruningTranslationLoader: (?, ?, ?).
I don't know why that doesn't work, but this way it should definitely work:
``` .ts
export function createTranslationLoader(http: HttpClient) {
return new PruningTranslationLoader(http); // specify more arguments if you want
}
and then
``` .ts
providers: [
{
provide: TranslateLoader,
useFactory: (createTranslationLoader),
deps: [HttpClient],
},
],
(We're doing this for TranslateLoader.)
@ffdybuster
But I want to solve the missing translation issue.
This does not solve the missing translation issue.
before I have done in this way.
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
providers: [
{
provide: TranslateLoader,
useFactory: (createTranslationLoader),
deps: [HttpClient],
},
],
I have translation like this
// en-US.json file
"Close": "Close",
"Get Started": "Get Started"
// da-DK.json file
"Close": "",
"Get Started": ""
this does not show the value for Get Started and Close when i choose da-DK as language.
I want it to show the key if value is empty
I just told you how to use the piece of code @CodeAndWeb pasted, since you had trouble with that. In case that code doesn't work for you, you could try debugging it to find out what the problem is.
The loader code I provided here removes the empty translations. ngx-translate now tries to use the translations from the default language (e.g translate.setDefaultLang('en');) - if this is not found you should get {Close}.
See also #830
this is exactly what I needed, thanks @CodeAndWeb
just sharing more functional version of process function for those who are interested
function process(obj) {
return Object.keys(obj)
.filter(key => obj.hasOwnProperty(key) && obj[key] !== '')
.reduce((res, key) => (res[key] = typeof obj[key] === 'object' ? process(obj[key]) : obj[key], res), {});
}
Using the code from above comments, following is more cleaner example.
Create a new file /src/app/pruning-loader.ts
import { HttpClient } from '@angular/common/http';
import { TranslateLoader } from '@ngx-translate/core';
import { map } from 'rxjs/operators';
export class PruningTranslationLoader implements TranslateLoader {
constructor(
private http: HttpClient,
private prefix: string = '/assets/i18n/',
private suffix: string = '.json') {
}
public getTranslation(lang: string): any {
return this.http.get(`${this.prefix}${lang}${this.suffix}`)
.pipe(map(
(result: object) => this.process(result)
));
}
private process(object: object) {
return Object.keys(object)
.filter(key => object.hasOwnProperty(key) && object[key] !== '')
.reduce((result, key) => (result[key] = typeof object[key] === 'object' ? this.process(object[key]) : object[key], result), {});
}
}
And then in your app.module.ts file, change the following line
import { PruningTranslationLoader } from './pruning-loader';
...
// required for AOT compilation
export function HttpLoaderFactory(http: HttpClient) {
return new PruningTranslationLoader(http); // <--- change here
}
Assuming you have already configured your module imports like this
imports: [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
...
]
I guess you can just do:
export class CustomHandler implements TranslocoMissingHandler {
handle(key: string, config: TranslocoConfig) {
return key; // Returning original string
}
}
And in your app.module.ts
{
provide: TRANSLOCO_MISSING_HANDLER,
useClass: CustomHandler
}
Most helpful comment
You can use this modified loader code. It removes empty strings from the files: