Home > Software design >  Updating User data display in Angular
Updating User data display in Angular

Time:11-23

I'm working on a project for which I have a question. I'm quite new to Angular and still trying to master the Observables, the Services and the interfaces ^^.

I'm working on a feature for an app that would allow the user to see the sidebar as if he was another user (who gave him the right to do so)

So the logic I'm trying to implement, is that after the selection of the profile I'm calling a method to switch the user display

My HTML

<select (change)="switchUser($event)">

This switchUser method is in sidebar-component.ts:

 getUser(userMatricule:any)
  {
    console.log(userMatricule)
    this.userData.getUserData(userMatricule).subscribe((response) => {              
      this.user = response.data
      console.log(this.user)
    })
  }
  switchUser(event:any)
  {
    console.log(event.target.value)
    this.userData.setUser(event.target.value)
    this.userData.userMatriculeSource.subscribe(x=>this.userId=x)
    console.log(this.userId)
    this.getUser(this.userId)
    **console.log(this.user)**
  }

And finally the user.service.ts

getUserData(matricule:string): Observable<any> {
this.apiUrl = this.baseUrl matricule
this.headers = new HttpHeaders().set('Access-Control-Allow-Origin', '*');
return this.http.get(this.apiUrl)

}

But the thing that I don't understand, is that when I run the code everythign works as it is suppose to. But when I console.log the different step I can see that the previous User is still showing on the last console.log of the switchUser() method.

I thought it could be a misunderstanding on my side, but I want to make sure that I don't run an unecessary request when switching User.

Thanks for your help!

CodePudding user response:

You need to understand how asynchronous fetching of data works. Read this canonical post with it's question in full.

One key point you do not know when the data will be assinged outside the subscription. In other words, you need to subscribe to observables where it's response is needed.

You need to use

  1. RxJS tap operator to perform side-effects like console.logs or assigning value to variables like this.userId = userId.

  2. RxJS map operator to transform the emitted data. In your case returning the data property from the emitted object.

  3. RxJS switchMap higher order mapping operator to switch from one observable to another. In your case switching from userMatriculeSource observable to getData() observable.

import { Observable } from 'rxjs';
import { map, switchMap, tap } from 'rxjs/operators';

getUser(userMatricule:any): Observable<any> {
  return this.userData.getUserData(userMatricule).pipe(
    map((response: any) => response.data)
  );
}

switchUser(event: any) {
  this.userData.setUser(event.target.value);
  this.userData.userMatriculeSource.pipe(
    tap((userId: any) => this.userId = userId),
    switchMap((userId: any) => this.userData.getData(userId))
  ).subscribe({
    next: (userId: any) => {
      console.log(userId);
    },
    error: (error: any) => {
      // handle errors
    }
  });
}
  • Related