0

my App structure is the following (app-component):

<app-navbar></app-navbar>
<router-outlet></router-outlet>
<app-footer></app-footer>

In the navbar I want to display the user's name, the problem is that in order to do that, there are two ways:

  1. In the navbar component I can read the current logged user onInit, get the name and display it. This way works just fine with the exception that it won't work correctly until you reload the page (or call navbar's onInit in order to read the user and get the value). If done this way, I would need to call navbar's onInit through login component (which is inside the <router-outlet>) after all data has been set.

  2. The other way is following this post (section 3. Siblings) which would mean to make an output in login component sending the user's name (this works so far), receiving it in app component (through the router-outlet tag) and sending the received data through an input in navbar component. I've also tried this, but app component won't receive the data (I'm guessing due to being inside a router-outlet).

<app-navbar [nombreNav]="nombreParent"></app-navbar>
<router-outlet (nombreLogin)="recibeNombre($event)"></router-outlet>
<app-footer></app-footer>

(nombreLogin is the Output EventEmitter in login component; recibeNombre() is the method in app component which should get the name and set it's value to nombreParent, which will be inputted to navbar component. I'm not pasting the code because it's literally that and it's the same as in the post)

So I would need either a way of calling navbar's onInit (which I've seen is possible with the use of outputs the same way as option 2) or send data through the <router-outlet>. How could I solve this?

Thanks.

1 Answers1

1

You need to use a service. A possible solution, if it is your logincomponent that holds the value, is to create a service which shares this value:

export class LoginInfoService {

  public loginNameSubject = new BehaviorSubject<string>('');

  constructor() { 

  }

  public broadCastLoginName(name:string){
    this.loginNameSubject.next(name);
  }
}

Then, the components which set this value (ex: your logincomponent) AND all components that need to read this value (ex: your navbar) need to be injected with this service so they can manage or read this shared observable:

export class NavbarComponent{

    public loginName: Observable<string>;

    constructor(private loginInfoService: LoginInfoService) {

      this.loginName = this.loginInfoService.loginNameSubject.pipe();

      ....

    }

in navbar.component.html:

<span>{{loginName | async}}</span>
export class LoginComponent{

    public loginName: string;

    constructor(private loginInfoService: LoginInfoService) {}

    someFunction(){
        ....
        this.loginInfoService.broadCastLoginName(loginName);
        ....
    }
Cédric S
  • 479
  • 3
  • 10
  • That worked! I already had a service for some global variables where I actually got the user's id, so I got the name through there. Thanks a lot! – Moises Pantion Loza Feb 09 '21 at 12:28