Angular 2 ngrx / store вызывает вызов службы Observable в результате другого вызова службы Observable

Я пытаюсь изучить и понять Rxjs и ngrx / store

У меня есть два вызова api, первый дает мне массив имен персонажей, второй дает мне инвентарь персонажа.

Как запустить вторую функцию через массив, возвращаемый первой, с помощью ngrx / store action / reducers / effects?

Это служебные функции:

public getCharacterNames(): Observable<string[]> {
  return this._http.get(this._url + '/characters?access_token=' + this._key)
    .map((res: Response) => res.json())
    .catch((error: any) => Observable.throw(error.json().error || 'server error'));
}

public getCharactersInventory(characterName: string): Observable<Bag[]> {
  return this._http.get(this._url + '/characters/' + encodeURI(characterName) + '/inventory?access_token=' + this._key)
    .map((res: Response) => res.json())
    .catch((error: any) => {return Observable.throw(error.json().error || 'server error'); });
}

Это действия:

public loadCharacters(): Action {
  return {
    type: Gw2Actions.LOAD_CHARACTERS
  };
}

public loadCharactersSuccess(characters: Character[]) {
  return {
    type: Gw2Actions.LOAD_CHARACTERS_SUCCESS,
    payload: characters
  };
}

Это редуктор:

  case Gw2Actions.LOAD_CHARACTERS_SUCCESS: {
    return action.payload;
  }

И вот эффект, который я пробовал использовать:

@Effect() private loadCharacters$: Observable<Action> = this._actions$
  .ofType(Gw2Actions.LOAD_CHARACTERS)
  .map((action) => action.payload)
  .switchMap(() => this._gw2Service.getCharacterNames())
  .map((characterNames) => {
      let characters = [];
      characterNames.forEach((characterName) => {
        let characterBags = this._gw2Service.getCharactersInventory(characterName)
          .subscribe((res) => res);
        characters.push({
          name: characterName,
          bags: characterBags
        });
      });
      return characters;
    }
  )
  .map((characters: Character[]) => this._gw2Actions.loadCharactersSuccess(characters));

person vilkatis    schedule 18.02.2017    source источник
comment
.map((characterNames) часть кажется мне неправильной, но я не могу понять, что там нужно сделать: |   -  person Pankaj Parkar    schedule 18.02.2017


Ответы (1)


Я предлагаю разделить две проблемы: Rxjs и ngstore. Ниже приведен подход к разрешению инвентаря по именам персонажей. Надеюсь, вы сможете сопоставить это с вашим эффектом ngstore.

let charNames$ = Rx.Observable.of([{name: 'a'}, {name: 'b'}, {name: 'c'}]); //mock names
let getInventoryFromName = name => Rx.Observable.of({owner: name}).delay(1000); //mock inventory

let result$ = charNames$.switchMap(names => Rx.Observable.forkJoin(names.map(n => getInventoryFromName(n.name))));

result$.subscribe(res => console.log('got some inventory/user pairs: ', res));
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>

person corolla    schedule 18.02.2017
comment
Я попытался реализовать что-то подобное, но не смог заставить его работать .. Думаю, я что-то упускаю или неправильно понимаю - person vilkatis; 20.02.2017