Reputation: 5826
I'm building an app where you can change between two languages any time you want. I've got a mock-service that provides me the phrases I use. When the user clicks on language link, the language in mock-service is changed, but I need to somehow listen to the changes when I'm getting the phrases, so service is returning me the updated phrase in Language I want.
LangService.ts:
activeLang :string = 'EN';
getPhrase(phrase :string) :string{
if(this.activeLang == 'EN'){
return this.EN[phrase];
} else {
return this.CZ[phrase];
}
}
changeLanguage(lang :string) :void{
if(lang == 'EN' || lang == 'CZ'){
this.activeLang = lang;
}
}
Then some OtherComponent.ts:
setPhrase(phrase :string){
this._langService.getPhrase(phrase);
// Here I need to subscribe to getPhrase to get the latest updates
// If I'm right and if it's possible
}
UPDATE
I made some corrections. LangService now has the Observable that we can listen to, but listener only works for component that triggers the method changeLanguage(). I want to be able to change the language from my NavigationComponent and catch the change in some OtherComponent.
LangService.ts:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class LangService {
private activeLang = 'EN';
private activeLangSubject = new Subject<string>();
activeLang$ = this.activeLangSubject.asObservable();
// Objects EN and CZ with properties, etc.
getPhrases(phrases :Array<string>){
if(this.activeLang == 'EN'){
let response = <any>{};
for(let i = 0; i < phrases.length; i++){
response[phrases[i]] = this.EN[phrases[i]];
}
console.log('refresh');
return JSON.stringify(response);
} else {
let response = <any>{};
for(let i = 0; i < phrases.length; i++){
response[phrases[i]] = this.CZ[phrases[i]];
}
return JSON.stringify(response);
}
}
changeLanguage(lang :string){
if(lang == 'EN' || lang == 'CZ'){
this.activeLang = lang;
this.activeLangSubject.next(lang);
}
}
NavComponent.ts:
import { Component, OnInit } from '@angular/core';
import { LangService } from '../lang.service';
@Component({
moduleId: module.id,
selector: 'app-nav',
templateUrl: 'nav.component.html',
styleUrls: ['nav.component.css'],
providers: [LangService]
})
export class NavComponent implements OnInit {
langs :Array<string> = ['EN', 'CZ'];
constructor(
private _langService :LangService) {
}
changeLanguage(lang :string) :void{
this._langService.changeLanguage(lang);
}
}
with NavComponent.html:
<li *ngFor="let lang of langs">
<a (click)="changeLanguage(lang)">{{ lang }}</a>
</li>
OtherComponent.ts:
import { Component, OnInit } from '@angular/core';
import { LangService } from '../lang.service';
import { NavComponent } from '../nav/nav.component';
@Component({
moduleId: module.id,
selector: 'all-notes',
templateUrl: 'notes.component.html',
providers: [NoteService, LangService],
directives: [NavComponent]
})
export class NotesComponent implements OnInit {
mode = 'Observable';
postPhrases :Array<string> = [
"alertTitle", "alertText", "options", "detailsBtn","editBtn","deleteBtn",
"addBtn", "serverResp", "actionMessage", "responseMessage", "note"
];
getPhrases :Object;
constructor(
private _langService :LangService) {
}
ngOnInit() {
this.updatePhrases(this.postPhrases);
// This one doesn't work
this._langService.activeLang$.subscribe(
success => this.updatePhrases(this.postPhrases),
error => console.log(error),
() => console.log('complete')
);
}
updatePhrases(phrases :Array<string>) :void {
this.getPhrases = JSON.parse(this._langService.getPhrases(phrases));
}
}
My question now is how can I listen for the changes on OtherComponent, so I can use method updatePhrases() to update phrases.
Upvotes: 0
Views: 218
Reputation: 5826
So basically the whole thing I needed was to create a service LangService with 3 variables.
activeLang: string 'EN';
activeLangSubject: Subject<string> = new Subject<string>();
activeLangObservable: Observable<string> = this.activeLangSubject.asObservable();
After that, I needed to add the LangService to the right scope. I wanted that to be global, so I put it as a provider to bootstrap method in main.ts
file.
bootstrap(AppComponent, [LangService]);
Of course I needed to import it before providing it to bootstrap.
After providing it in bootstrap all I needed to do was:
constructor(private _langService: LangService) {}
,Subscribe to it
ngOnInit() {
this._langService.langServiceObservable.subscribe(
response => console.log('Changed! Active Language: ' + response),
error => console.log('Error! Description: ' + error)
);
}
In case you don't use ngOnInit() you can also subscribe to changes inside constructor()
Upvotes: 0
Reputation: 8073
This sounds like something you would use a pipe for:
import { Pipe, PipeTransform, Injectable } from '@angular/core'
@Injectable()
@Pipe({ name: 'myTranslatePipe' })
export class IndicatorHeadersPipe implements PipeTransform {
public transform(
phrase: string,
activeLang: string
) {
if(activeLang == 'EN'){
return this.EN[phrase];
} else {
return this.CZ[phrase];
}
}
}
Do not forget to add the pipe to your NgModule
declarations
And then, in your component
@Component({
selector: 'my-selector',
template: `
<div>{{ 'My text' | myTranslatePipe : activeLang }}</div>
`,
})
export class PageIndicatorComponent {
private activeLang: string
changeLanguage(lang :string) :void{
if(lang == 'EN' || lang == 'CZ'){
this.activeLang = lang;
}
}
}
However, I would recommend just using a translation module, like ng2-translate
Upvotes: 1