Reputation: 53
The last previous account name is displayed. It's only when I refresh the browser the displayed name changes to the current logged in account.
below is the Auth service.
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
import { map } from 'rxjs/operators';
import { DefaultUrlSerializer } from '@angular/router';
import { JwtHelperService } from '@auth0/angular-jwt';
import { Observable } from 'rxjs';
import { yearsPerPage } from '@angular/material/datepicker';
@Injectable({
providedIn: 'root'
})
export class AuthService {
baseUrl = environment.apiUrl + 'auth/';
decodedToken: any;
jwtHelper = new JwtHelperService();
constructor(private http: HttpClient) { }
login(model: any) {
return this.http.post(this.baseUrl + 'login', model)
.pipe(
map((response: any) => {
const user = response;
if (user) {
localStorage.setItem('token', user.token);
localStorage.setItem('user', JSON.stringify(user.user));
this.decodedToken = this.jwtHelper.decodeToken(user.token);
localStorage.setItem('role', JSON.stringify(this.decodedToken.role));
}
})
);
}
register(model: any) {
return this.http.post(this.baseUrl + 'register', model, { responseType: 'text' });
}
loggedIn() {
const token = localStorage.getItem('token');
return !this.jwtHelper.isTokenExpired(token);
window.location.reload();
}
role() {
return localStorage.getItem('role');
}
}
I’m getting the logged in details from the local storage and storing the details into a variable called userDisplayName in the navbar component. As you can see below the code is in ngONInit method. “this.userDisplayName = JSON.parse (localStorage.getItem('user'));”
import { AddTaskComponent } from './../addTask/addTask.component';
import { AuthService } from './../_services/auth.service';
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { UpdateTaskComponent } from '../updateTask/updateTask.component';
import { Router } from '@angular/router';
import { UserMemberService } from '../_services/userMember.service';
import { StateStorageService } from '../_services/stateStorage.service';
@Component({
selector: 'app-navigation-bar',
templateUrl: './navigationBar.component.html',
styleUrls: ['./navigationBar.component.css']
})
export class NavigationBarComponent implements OnInit {
model: any = {};
loginReactiveForm: FormGroup;
role;
users: any[];
userAuthorised: boolean;
searchTask: FormControl;
Username: string;
userDisplayName;
constructor(
private authService: AuthService,
public dialog: MatDialog,
private router: Router,
private userMemberService: UserMemberService,
private stateStorageService: StateStorageService) { }
ngOnInit() {
this.initForm();
this.isUserAdmin();
// this.userDisplayName = this.authService.login(this.model);
this.userDisplayName = JSON.parse (localStorage.getItem('user'));
console.log(this.role);
}
login() {
this.model.username = this.loginReactiveForm.value.username;
this.model.password = this.loginReactiveForm.value.password;
this.authService.login(this.model).subscribe(next => {
this.loadUsers();
this.router.navigateByUrl('/CalendarView');
this.isUserAdmin();
}, error => {
console.log('failed to login');
});
}
isUserAdmin() {
// get users role
this.role = JSON.parse(localStorage.getItem('role'));
console.log('this is role = ' + this.role);
// if user is not an Admin
if (this.role !== 'Admin') {
this.userAuthorised = false;
console.log('value of auth is = ' + this.userAuthorised );
} // if user is an Admin
else {
// list of users for the drop down
this.userAuthorised = true;
console.log('value of auth is = ' + this.userAuthorised );
}
}
loadUsers() {
this.userMemberService.getUsers().subscribe((data) => {
this.users = data;
this.stateStorageService.setUserMemberStorage(this.users);
}, error => {
console.log(error);
});
}
initForm() {
this.loginReactiveForm = new FormGroup({
username: new FormControl(),
password: new FormControl()
});
this.searchTask = new FormControl();
}
// has the user logged in
loggedIn() {
return this.authService.loggedIn();
}
loggedOut() {
const token = localStorage.removeItem('token');
const username = localStorage.removeItem('user');
const userId = localStorage.removeItem('role');
localStorage.removeItem('user');
}
}
Below is the html
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
<ul *ngIf="!loggedIn()" class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link">
<span class="sr-only"></span></a>
</li>
</ul>
<form *ngIf="!loggedIn()" class="form-inline my-2 my-lg-0" [formGroup]="loginReactiveForm"
(ngSubmit)="login()">
<input formControlName="username" class="form-control mr-sm-2"
type="text" placeholder="Username" aria-label="username">
<input formControlName="password" class="form-control mr-sm-2"
type="password" placeholder="Password" autocomplete="off" aria-label="password">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Login</button>
</form>
<div *ngIf="loggedIn()" class="username" style="position:relative; left:70%; color: white ;" >Username: {{userDisplayName.username}}</div>
<div style="position:relative; left:85%">
<button *ngIf="loggedIn()" class="btn btn-outline-success float-right"
type="submit" (click)="loggedOut()" [routerLink]="['/login']">Log Out</button>
</div>
</nav>
Why is is that the loggedin user is only displayed once the browser has been refreshed? I'm currently logged in as “Matt Briggs” but it shows “Sallyjones” on the navbar in the image. Link to the image is here
Upvotes: 0
Views: 1445
Reputation: 49
you can directly call it from your server to html page
get loggedInUser(): any {
const uname = localStorage.getItem('uname');
return uname;
}
In your html page
<li><a *ngIf="auth.isLoggedIncheck"><span class="glyphicon glyphicon-log-in"></span> Welcome{{auth.loggedInUser| uppercase}} </a> </li>
Upvotes: 0
Reputation: 714
Problem
The problem in your code is that you only set userDisplayName
once in ngOnInit. NgOnInit is only called once when the component is initialised. So this is why you need to refresh to see the new user from localstorage.
There's no other place where you change or update userDisplayName
...
Solution
I think your code could use a little refactoring to make it work like you expect. You're putting to much logic in your component code.
Save your decodedToken in a currentUser
subject which is exposed as an observable ==> By doing this, you can subscribe to this observabel in your component's ngOnInit function. This way every change will be shown in your component too.
This is a tutorial which gives a complete overview of how you can implement authentication in Angular. Give it a good read and try this out in your code. https://jasonwatmore.com/post/2020/07/09/angular-10-jwt-authentication-example-tutorial#authentication-service-ts
Upvotes: 1
Reputation: 1563
this sounds like a change detection problem. Can you use a Subject
to store the userDisplayName
?
e.g.
export class NavigationBarComponent implements OnInit {
...
userDisplayName = new Subject<{username: string}>;
...
const _u = JSON.parse(localStorage.getItem('user'));
this.userDisplayName.next(_u);
then in your template
<div *ngIf="loggedIn()"
class="username"
style="position:relative; left:70%; color: white ;" >
Username: {{(userDisplayName | aasync)?.username}}
</div>
Using a subject will cause ng to redraw the ui when the value of userDisplayName
changes.
I am guessing that ng is drawing the dom on init, when there is an old value in userDisplayName
and doesn't know the value has changed. Using a subscribable will fix that.
Upvotes: 0