RXJS Observables - вызов http для каждого значения индекса и результат слияния - PullRequest
0 голосов
/ 26 мая 2018

Я делаю http-вызов, чтобы получить массив с objs.И теперь я хочу вызвать для каждого объекта, которые возвращают мне ID еще один http-вызов.В конце концов я хочу получить один наблюдаемый результат.

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

getStats(tag: string) {
    return this.service.getClanByClanTag(tag)
        .map(clan => {
            return clan.memberList; //the arr that return the ID's
        })
        .switchMap((member: PlayerByMemberListType[]) => {
            return member; // singleObj of the arr
        })
        .concatMap((singleMember) => {
            return this.service.getPlayerData(singleMember.tag).map(player => {
                //push data to the new arr which should return only one time
                this.newArr.push({
                    tag: singleMember.tag,
                    name: singleMember.name,
                    warStars: player.warStars,
                    trophiesNightBase: singleMember.versusTrophies
                });
                return this.newArr;
            });
        });
}

Вот что печатает консоль после подписки на нее:

Array [ {…} ]
Array [ {…}, {…} ]
Array(3) [ {…}, {…}, {…} ]
Array(4) [ {…}, {…}, {…}, {…} ]
Array(5) [ {…}, {…}, {…}, {…}, {…} ]
...

Я знаю, мне нужен какой-то Observable.forkJoinно я не знаю, как интегрировать это в код.

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Итак, в основном вы хотите достичь этого.

  1. Получить информацию о клане
  2. Используя информацию о клане из шага 1, получить memberList в клане
  3. Для каждого участника в memberList получите игроков

. Вам нужно будет придумать способ сохранить информацию на step2, когда до switchMap на step3.Обычно мы будем использовать Subject, но в случае, если вы не хотите, просто map Observable для сохранения данных:

getStats(tag: string) {
    return this.service.getClanByClanTag(tag)
        .map(clan => {
            return clan.memberList; //the arr that return the ID's
        })
        .switchMap((memberList: PlayerByMemberListType[]) => {
            //note that the following map is a function of javascript array, not Observable
            //it returns an array
            let arrayOfObservables = memberList.map(singleMember => {
                this.service.getPlayerData(singleMember.tag)
                //map the data so as to preserve the data of singleMember 
                //by creating a new object, using Object.assign
                    .map(playerData => {
                        return Object.assign({memberData: singleMember}, playerData,)
                    });
            })
            return Observable.forkJoin(arrayOfObservables);
        })
        .map(players => {
            //players is an array of Object that is the format of {memberData:singleMember, playerData:player)
            //perform Object destructuring method
            return players.map(({memberData,playerData}) => {
                return {
                    tag: memberData.tag,
                    name: memberData.name,
                    warStars: playerData.warStars,
                    trophiesNightBase: memberData.versusTrophies
                }
            })
        })
}
0 голосов
/ 26 мая 2018

Попробуйте что-то вроде этого:

this.service.getClanByClanTag(tag)
    .mergeMap(clan => clan.memberList)
    .mergeMap(
        member => this.service.getPlayerData(member.tag), // supposedly this returns an observable
        (member, player) => ({ 
            tag: member.tag,
            name: member.name,
            warStars: player.warStars,
            trophiesNightBase: member.versusTrophies
        })
    )
    .toArray()
...