Цепочка вызовов HttpClient в Angular 6 - PullRequest
0 голосов
/ 30 ноября 2018

Я думаю, что прочитал более 100 сообщений на эту тему, и до сих пор не могу понять, как связать два вызова HttpClient с помощью rxjs в Angular 6.

Допустим, у меня есть служба с такой подписью:

  GeoService {
      getState(): Observable<string> {
          return this.http.get<string>(stateURL);
      }
      getCities(state: string): Observable<string[]> {
          return this.http.get<string[]>(citiesURL + state);
      }
   }

Я не могу понять, как получить штат и соответствующий список городов в моем компоненте:

import { Observable } from 'rxjs';
import { map, flatMap, mergeMap, filter, switchMap } from 'rxjs/operators';

...

 ngOnInit() {

      this.svc.getState().
        pipe(map((state) => {
            this.state = state;
            return this.svc.getCities(state);
          }),
          mergeMap((cities) => this.cities = cities))
        ).
        subscribe(console.log('done'));

Код выше в одном измои 20 случайных попыток объединить pipe / map / mergeMap / подписку всеми возможными способами ... рабочий пример был бы очень признателен:)

Спасибо!

Редактировать: Нетиз «возможных дубликатов» постов содержат реальный пример, который работает

Ответы [ 3 ]

0 голосов
/ 30 ноября 2018

Вы можете сделать что-то вроде этого

this.svc.getState().pipe(
     tap(state=>this.state=state),
     switchMap(this.svc.getCities))
.subscribe(cities=>{
    //got the cities
})

оператор карты здесь, чтобы преобразовать выбрасываемое значение, но оператор касания используется, чтобы сделать что-то без изменения испускаемого значения наблюдаемой.

обратите внимание, что switchMap (this.svc.getCities) эквивалентен switchMap (state => this.svc.getCities (state)

0 голосов
/ 30 ноября 2018

Вы были почти там:

    this.svc.getState().
        pipe(
            mergeMap((state) => {
                return this.svc.getCities(state).pipe(map(cities => {
                    return { state: state, cities: cities }
                }));
            }),
        ).subscribe(stateAndCities => console.log(stateAndCities));

Советую прочитать эту статью:

https://blog.strongbrew.io/rxjs-best-practices-in-angular/#using-pure-functions

Это также объясняет, почему вы не должны взаимодействовать с глобальными переменнымив операторах rxjs.

0 голосов
/ 30 ноября 2018

21-я попытка была бы правильной; -)

this.svc.getState().
    pipe(mergeMap((state) => {
        this.state = state;
        return this.svc.getCities(state);
    }),
    tap((cities) => this.cities = cities)))
.subscribe(() => console.log('done'));

Цепная наблюдаемая идет внутрь mergeMap.Вы можете думать об этом как:

Сначала map входящее уведомление в Observable, затем merge результирующее «внутреннее» Observable в «внешнее»"Наблюдаемый

Кроме того, используйте tap вместо map, если вы собираетесь изменить внешнее состояние.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...