Using ngx-translate to switch the language of a Form in your angular application
You would have come across applications where they provide an option to view it in the language you prefer. This kind of feature would not be suitable for all applications.
The question is if I change the language, do I change the language of everything in the application? Not really. What I change are the labels, headings etc.
ngx-translate is an npm package that’s helps achieve this job.
If you are interested in how @angular/localize can help translating the language of the application,you can checkout the below story.
Setup is quite simple! All you need to do is install the below 2 packages and make some changes in app.module of the angular application.
npm install @ngx-translate/core — save
npm install @ngx-translate/http-loader — save
You need to import these modules in app.module.ts to make it work.
App.module.ts
import { TranslateLoader, TranslateModule } from ‘@ngx-translate/core’;
import { TranslateHttpLoader } from ‘@ngx-translate/http-loader’;export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http);
}@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
AppRoutingModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
],
bootstrap: [AppComponent]
})
export class AppModule { }
Component Template:
<form class=”form-group”>
<label>Select Language:</label><select class=”form-control” [(ngModel)]=”selectLang” name=”selectLang” (change)=”setTransLanguage()”>
<option *ngFor=”let lang of TransLang” value=”{{lang}}”>{{ lang }}</option>
</select>
</form><form class="form-group">
<label>{{'LoginFormLabels.username' | translate}}:</label>
<input type="text" class="form-control" [(ngModel)]="username" name="username"><label>{{'LoginFormLabels.password' | translate}}:</label>
<input type="text" class="form-control"[(ngModel)]="password" name="password">
<button class="btn btn-primary" type="submit">{{'LoginFormLabels.submit' | translate}}</button>
</form>
We have a dropdown to select the language and a Login Form. The selected language will be the language of labels and buttons of the Form.
The translate is added after the pipe for the Labels and button names. The Translation service will be applied to those only.
You would have noticed that all labels and buttons names are not hardcoded in the template. Instead they are an interpolation of an object’s property in the Class as below.
<label>{{'LoginFormLabels.username' | translate}}:</label>
<label>{{'LoginFormLabels.password' | translate}}:</label><button class="btn btn-primary" type="submit">{{'LoginFormLabels.submit' | translate}}</button>
Class:
export class AppComponent {username:string=””;
password:string=””;
selectLang:string=””;
TransLang=[];LoginFormLabels={
username:”Username”,
password:”Password”,
submit:”Submit”
}constructor(public translate: TranslateService){
translate.setDefaultLang(‘en’);
translate.addLangs([‘en’, ‘fr’]);
translate.use(‘en’);
}setTransLanguage(){
this.translate.use(this.selectLang);
}getTransLanguage(){
this.TransLang=[…this.translate.getLangs()];
}ngOnInit(){
this.getTransLanguage();
}
}
We have provided the initial values for the labels and buttons below.
LoginFormLabels={
username:”Username”,
password:”Password”,
submit:”Submit”
}
The TranslateService is imported from @ngx-translate/core package.
constructor(public translate: TranslateService){
translate.setDefaultLang(‘en’);
translate.addLangs([‘en’, ‘fr’]);
translate.use(‘en’);
}
The default language to be used as a fallback is set by translate.setDefaultLang(‘en’).
translate.addLangs() accepts an array of languages that can be used in the application.
translate.use(‘en’) sets the language to be currently used.
Now how are the languages populated in the dropdown?
When the component is loaded,getTransLanguage() is called.
getTransLanguage(){
this.TransLang=[…this.translate.getLangs()];
}
translate.getLangs() retrieves the array of languages available for this application i.e en and fr. This is stored in a variable TransLang. We are iterating over this TransLang to form the dropdown as below
<select class=”form-control” [(ngModel)]=”selectLang” name=”selectLang” (change)=”setTransLanguage()”>
<option *ngFor=”let lang of TransLang” value=”{{lang}}”>{{ lang }}</option>
</select>
The next question is how should the language switch when it is selected in the dropdown?
So once I select an option in the dropdown, setTransLanguage() is called, where I am setting the current language to be used to the ngModel of the dropdown.
setTransLanguage(){
this.translate.use(this.selectLang);
}
The package uses Translation files to acheive this task of translation. We need to create translation files for each language. Now since i have used just 2 languages, I will have 2 json files located in the i18n folder in the assets folder.
By default the package will look for the json files in the path /assets/i18n/.If the selected language is ‘fr’ then the filename must be fr.json.So the complete path will be /assets/i18n/fr.json
This can be changed by adding the optional 2nd and 3rd parameters to the TranslateHttpLoader Class below.
The 2nd parameters is the folder path. The file name will be the same as the language selected using translate.use(). The 3rd paramter will be set the filename suffix.
export function HttpLoaderFactory(http: HttpClient) {return new TranslateHttpLoader(http, "/public/lang-files/", "-lang.json");
}
en.json
{
“LoginFormLabels.username”:”Username”,
“LoginFormLabels.password”:”Password”,
“LoginFormLabels.submit”:”Submit”
}
fr.json
{
“LoginFormLabels.username”:”Nom d’utilisateur”,
“LoginFormLabels.password”:”mot de passe”,
“LoginFormLabels.submit”:”Soumettre”
}
As you see both the json files contain an object with the same properties. Only the values differ in language.
The package uses these files to switch from English to French and vice-versa when I select an option in the dropdown.