In my Angular 13 I have this code:
JSON Response from ASP.NET Core Web API:
{
"code": 200,
"error": false,
"message": "Logged In Successful",
"results": {
"token": "thisismytoken...",
"user": {
"id": 1,
"username": "Ashwel",
},
"roles": [
"SuperAdmin"
]
}
}
ANGULAR
user.ts:
export interface IResponse<T> {
message: string;
error: boolean;
code: number;
results: T;
}
export interface IUser
{
username?: string;
token?: string;
roles?: string[];
}
auth.service:
export class AuthService {
baseUrl = environment.apiUrl;
private currentUserSource = new ReplaySubject<IUser | null>(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.token){
user.roles = [];
const roles = this.getDecodedToken(user.token).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]));
}
}
auth.component:
export class AuthComponent implements OnInit {
loginForm!: FormGroup;
user!: IUser | null;
constructor(
private authService: AuthService,
private router: Router,
private toastr: ToastrService
) {
this.authService.currentUser$.pipe(take(1)).subscribe(user=> this.user = user);
}
myForm() {
this.loginForm = new FormGroup({
UserName: new FormControl('', Validators.required),
Password: new FormControl('', [Validators.required])
})
}
login(){
this.authService.login(this.loginForm.value).subscribe({
next: (res: any) => {
console.log(res);
this.toastr.success(res.message);
this.router.navigateByUrl('dashboard');
},
error: (error) => {
this.toastr.error(error.message);
}
})
}
}
This is the flow auth.component
-> auth.service
-> user.ts
:
What I intend to do is, when user submits to login:
localStorage
But instead of all these, I got this error in the inspect -> console:
ERROR TypeError: Cannot read properties of undefined (reading 'message')
When I did console.log(res) in auth.service
, I got undefined.
How do I resolve this error?
Thank you
I see two mistakes in your AuthService.login
method:
IUser
when based on the JSON you've posted it should be of IResponse<IUser>>
map
operator to trigger a side effect. map
is used to apply a transformation to the emitted values and therefore the map function should return the transform value. To trigger side effects you should use tap
.So you should modify the method as follows.
login(model: any){
return this.http.post<IResponse<IUser>>(this.baseUrl+'auth/login', model).pipe(
tap((response) => {
const user = response.results;
if(user){
this.setCurrentUser(user);
}
})
)
}
cheers