In my Angular-13 frontend and ASP.NET Core Web API, after successful login, I want to store User details into the localstorage.
From POSTMAN, I have this:
{
"status_code": 200,
"message": "Successfully Logged In",
"result": {
"token": "gggggffffffffffffdddddddddddd",
"user": {
"id": 3,
"user_name": "smith",
"last_login": "2022-01-03T12:35:26.0305649"
},
"roles": [
"Teacher"
],
}
}
Angular:
user.ts
:
export interface IUser {
userName?: string;
lastLogin?: Date;
token?: string;
roles?: string[];
expires?: Date;
}
auth.service.ts
:
export class AuthService {
baseUrl = environment.apiUrl;
private currentUserSource = new ReplaySubject<IUser>(1);
currentUser$ = this.currentUserSource.asObservable();
constructor(private http: HttpClient, private router: Router) { }
login(model: any){
return this.http.post(this.baseUrl+'auth/login', model).pipe(
map((res: IUser)=>{
const user = res;
if(user){
this.setCurrentUser(user);
}
})
)
}
setCurrentUser(user: IUser){
if(user){
user.roles = [];
const roles = this.getDecodedToken(user.token).role;//copy token to jwt.io see .role
Array.isArray(roles) ? user.roles = roles : user.roles.push(roles);
localStorage.setItem('user', JSON.stringify(user));
this.currentUserSource.next(user);
}
}
getDecodedToken(token: string) {
return JSON.parse(atob(token.split('.')[1]));
}
}
On Angular frontend, I have two dashboards: teacher-dashboard and student-dashboard
auth.component:
createForm() {
this.loginForm = new FormGroup({
UserName: new FormControl('', Validators.required),
Password: new FormControl('', [Validators.required, Validators.minLength(6), Validators.maxLength(80)])
})
}
login(){
this.authService.login(this.loginForm.value).subscribe(res=>{
this.router.navigateByUrl('/');
}, error=>{
this.toastr.error(error.error);
})
}
setCurrentUser is used to store user details in the LocalStorage.
However, after successful login I checked the LocalStorage (Application/LocalStorage) using inspect. It stores nothing there.
Where did I miss it and how do I correct that?
Thanks
console.log(res) gives:
Object
message: "Successfully Logged In"
result:
expires: "2022-01-05T12:01:35Z"
roles: ['Admin']
token: "This is the token"
user:
id: 1
is_password_changed: false
last_login: "2022-01-05T09:46:24.7719569"
user_name: "admin"
status_code: 200
map
is not the solution. If you want to do something on the response and the still can subscribe that in another component you have to use tap
instead. In your auth.service.ts
do it like:
login(model: any){
return this.http.post(this.baseUrl + 'auth/login', model).pipe(tap((res: IUser) => {
if (res) {
this.setCurrentUser(res);
}
}));
}
You also defined IUser
model as the input model for setCurrentUser
but you are passing wrong type of input in the function so you will get nothing in the function because your input does not have any of the desired properties and all the other ones that it has will be droped because the property name is not defined in the model.