angularrxjs

Subscribing to event outside router-outlet


I have this simple app.component.html:

<app-header></app-header>

<main>
    <router-outlet></router-outlet>
</main>

<app-footer *ngIf="currentUser"></app-footer>

I want app-footer to subscribe to events fired from components triggered by routing i.e. "inside" the router-outlet tag.

For some reason I just cant get this to work.

In my translation.service.ts I have these two lines:

private languageChanged$: Subject<string> = new Subject<string>();
public languageChanged: Observable<string> = this.languageChanged$.asObservable();

and in app-footer:

this.translationService.languageChanged.subscribe(() => {
    console.log('Language Changed');
    [my code here]
});

How can I trigger the code in app-footer? I know for sure that a language is nexted into languageChanged$.


Solution

  • Try BehaviorSubject which holds the emitted state, I think its a timing issue. Where the subscribe happens, after the subject is emitted, hence it's missing the emit.

    private languageChanged$: Subject<string> = new BehaviorSubject<string>('');
    

    Then you can subscribe to it and execute only when it has a value.

    this.translationService.languageChanged.subscribe((value: string) => {
        if(value) {
          console.log('Language Changed');
          [my code here]
        }
    });
    

    Make sure you have providedIn: 'root' set for the translation.service.ts

    The TranslationService should be removed from all providers array in your application, since it is already provided at the root level, by adding this.

    When you have the service in providers array, it always creates a new instance and if both components do not share the same instance then the emit will not be received.

    @Injectable({
        providedIn: 'root'
    })
    export class TranslationService {
        ...