Angular 2 ngrx / store在另一个Observable服务调用的结果上调用Observable服务调用

时间:2017-02-18 17:51:09

标签: angular rxjs observable ngrx ngrx-effects

我试图学习和理解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));

1 个答案:

答案 0 :(得分:0)

我建议将Rxjs和ngstore的两个挑战分开。以下是从字符名称解决库存的方法。希望您能够将其映射到您的ngstore效果中。

&#13;
&#13;
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));
&#13;
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
&#13;
&#13;
&#13;