Угловая подписка в рамках подписки - PullRequest
2 голосов
/ 01 апреля 2019

У меня есть следующий код, который состоит из нескольких подписок.Что мне нужно сделать, так это:

  1. Подписаться на activRoute для получения данных о пользователе и продукте.
  2. Получив данные о продукте, подпишитесь на сервис getSeller, используя данные о продукте.
  3. Подписаться на сервис getRating, используя возвращенные данные продавца.

Мой вопрос: есть ли лучший способ выполнить эту вложенную подписку?это хорошая практика, чтобы делать так?

this.activatedRoute.data.pipe(
 map((data) => {
    this.user = data['user'];
    this.product = data['product'];

    return this.product;
  })
).subscribe(result => {

  if (this.product === null) {
    this.router.navigate(['/home']);
  } else {
    this.displayCurrency = this.dataService.getCurrencySymbolById(this.product.currency);

    this.userService.getUser(this.product.createdBy).subscribe(seller => {
      this.seller = seller;

      this.ratingService.getRatingByUserId(seller.id).subscribe(rating => {
        this.rating = rating;
      })

    });
  }
});

Ответы [ 2 ]

3 голосов
/ 01 апреля 2019

Технически, вложенная подписка работает, но есть более элегантный и систематический способ справиться с этим.Вы действительно должны больше узнать о своих операторах RxJS.

Сначала мы используем mergeMap для отображения наблюдаемых значений из activRoute во внутреннюю наблюдаемую.

Затем мы используем forkJoin , чтобы объединить наблюдаемые в одно наблюдаемое значение, таким образом, возвращая само значение в .subscribe()

this.activatedRoute.pipe(
    tap(data => console.log(data)),
    mergeMap(data => {
      if (data.product === null) {
        this.router.navigate(['/home']);
      } else {
        const getCurrency = this.dataService.getCurrencySymbolById(data.product.currency);
        const getUsers= this.userService.getUser(data.product.createdBy);
        const getRatings = this.ratingService.getRatingByUserId(seller.id)
        return forkJoin(getCurrency, getUsers, getRatings);
      }
    })
  ).subscribe(res => {
    console.log(res[0]); // currency
    console.log(res[1]); // user
    console.log(res[2]); // ratings

  }

РЕДАКТИРОВАТЬ: Оказывается, я неправильно прочитал исходный вопрос, так как getRatingsByUserId зависит от getUser.Позвольте мне внести некоторые изменения.В любом случае, я оставлю код выше, как есть, и это хорошо для справки ОП.

this.activatedRoute.data.pipe(
  switchMap(data => {
    this.user = data['user'];
    this.product = data['product'];
    return this.userService.getUser(this.product.createdBy);
  }),
  switchMap(data => {
    if (this.product === null) {
      this.router.navigate(['/home']);
    } else {
      this.seller = seller;
      return this.userService.getRatingByUserId(this.product.createdBy); 
    }
  })
).subscribe(res => {
 console.log(res)
 // handle the rest
})
1 голос
/ 01 апреля 2019

Используйте switchMap для переключения на новую наблюдаемую.

this.activatedRoute.data.switchMap((routeData) => {
     this.user = routeData['user'];
     this.product = routeData['product'];
     return this.userService.getUser(this.product.createdBy);
    }).switchMap(seller => {
       this.seller = seller;
        return this.ratingService.getRatingByUserId(seller.id);
    }).subscribe(rating => {
      this.rating = rating;
    })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...