Updating header after sign in using router in angular

Viewed 70

I have an app as simple as this:

<app-header></app-header>
<app-top-menu></app-top-menu>
<router-outlet></router-outlet>

When the user loads the page, in the component <app-header> says "sign in", and that loads a route in the <router-outlet>. The thing is that when the user signs in, I navigate to other route, but the directive never reloads. Is there any dynamic way to update the text in <app-header> when user signs in without reloading the page?

I don't have much code to show because is irrelevant to the situation, so any idea is welcome.

UPDATE:

After the suggested answer I think that I might be doing something wrong because is not working:

@Injectable()
export class AuthService extends Service{

  private authenticated$: BehaviorSubject<boolean> = new BehaviorSubject(false);

  constructor(private http: HttpClient) {
    super()
  }

  signIn(input: SignInInput, success: (response: any) => void, failure: (error: any) => void): void {
    this.http.post<SignInInput>("....", input).subscribe({
      next: async (response: any) => {
        this.authenticated$.next(true);
        success(response)
      },
      error: (error: any) => {
        failure(error)
      }
    })
  }

 isAuthenticated(): Observable<boolean> {
    return this.authenticated$.asObservable();
  }
}

And in my header component I have this:

export class HeaderComponent implements OnInit {

  constructor(private authService: AuthService) {}

  welcomeText: string

  ngOnInit(): void {
    this.authService.isAuthenticated().subscribe((isAuthenticated: boolean) => {
      if (isAuthenticated){
        this.welcomeText = "username"
      }else{
        this.welcomeText = "Sign in"
      }
    });
  }
}

This is the template which always shows "Sign in":

<a class="u-align-right" routerLink="sign-in">
  {{welcomeText}}
</a>
1 Answers

Basically you are asking how to manage the state in your app. Simplest way to do it is by using a data service like this:

@Injectable()
export class AuthService {
  private authenticated$: BehaviorSubject<boolean> = new BehaviorSubject(false);

  isAuthenticated(): Observable<boolean> {
    return this.authenticated$.asObservable();
  }

  setAuthenticated(authenticated: boolean) {
    this.authenticated$.next(authenticated);
  }
}

so you keep the authentication state in the authenticated$ Subject.

In your login component, when the user successfully logs in the app, you call

this.authService.setAuthenticated(true)

In your header component you listen for the authentication status

this.authService.isAuthenticated().subscribe((isAuthenticated: boolean) => {
  // if true hide the sign in button
});

There are other ways to handle state in your application, you could incorporate a library like ngrx or ngxs that is built for this purpose, but for something simple services like this will suffice.

Related