0

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!

SamBslm
  • 13
  • 2

1 Answers1

0

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
    }
  });
}
ruth
  • 29,535
  • 4
  • 30
  • 57
  • Hi Michael. thanks for the feedback! The link was quite enlightening, i've always has difficulties to understand the asynchronous concept and here it was very well explained. Thanks also for the feedback on my code and the explanations, it makes way more sense! I'll keep working on learning the concept of the Observables! Have a good day! – SamBslm Nov 22 '21 at 16:18