Home > Enterprise >  Angular data undefined outside subscribe
Angular data undefined outside subscribe

Time:04-08

I know it was asked million times, but i really don't understand how it works. I tried to new Promise, but there is nothing inside then() i tried to do it with mergeMap but messed up. I want to get current user's favorite items. And to do it i'm calling this method:

user: IUser;
tracks: ITrack[] = [];

public getFavorites() {
    this.userService.getFavourite(this.user.id).subscribe(
      (tracks: ILike[]) => {
        if (tracks) {
          tracks.forEach(track => {
            this.tracks.push(this.loadTracks(track.id));
          });
        }
      }
    );

For this method i need user id which i get like this and :

private async loadUser() {
    this.accountService.currentUser$.subscribe((user: IUser) => {
      // getting into another service, because currentUser don't have id
      this.userService.getUserByUsername(user.username).subscribe((u: IUser) => {
        this.user = u;
      })
    })
  }

and and also track_id:

loadTracks(id: number) {
    let track: ITrack;
    this.trackService.getTrack(id).subscribe(t => track = t);
    return track;
}

ngOnInit():

this.loadUser();
this.getFavorites();

How to do it properly with mergeMap?

CodePudding user response:

I think you will want to use switchMap in this case.

this.accountService.currentUser$.pipe(
    switchMap((user: IUser)=> {
       return this.userService.getUserByUsername(user.username);
    }),
    tap(user => {
       console.log(user); // Check if its work
    }),
    switchMap(user => {
       return this.userService.getFavourite(this.user.id)
    }),
    tap(tracks => {
       console.log(tracks); // Now you have track
    })
); // You can .subscribe() here or use async pipe

You also can split this logic and reuse

const getUser$ = this.accountService.currentUser$.pipe(
    switchMap((user: IUser)=> {
       return this.userService.getUserByUsername(user.username);
    })
);

Read more about Higher order observable here

CodePudding user response:

You are probably looking for switchMap instead of mergeMap. mergeMap should be used when you want to combine the results of observables.

Here is a working example: https://stackblitz.com/edit/typescript-sdf2gy?file=index.ts

let userLocation$ = of({ userId: 123 }).pipe(delay(2000));
let getFavourite = function (userId) {
  return of({ someData: 'someData: '   userId }).pipe(delay(1000));
};

userLocation$
  .pipe(switchMap((data) => getFavourite(data.userId)))
  .subscribe((v) => console.log(v));
  • Related