У меня есть объект, который должен быть заполнен информацией, которую я должен получить по проводам.Новая информация должна храниться в том же объекте
Например:
const apps = {
com.foobar.bar: {
title:pancake,
existingInfo: bar
},
com.company.android: {
title: foobar,
existingInfo: barfoo
}
}
Для каждого идентификатора внутри приложений я хочу вызвать API отдыха, который даст некоторые дополнительные поля, которые я могу добавитьк объекту.Поток не должен ждать завершения всех остальных вызовов, он должен начинаться с возврата начального значения и затем генерировать обновленный объект для каждого полученного restcall.
В первый раз любой из остальных вызовов возвращает егодолжен заполнять только правильное поле.
{
com.foobar.bar: {
title:pancake,
existingInfo: bar,
newStuff: foobar //let say this is the response we get from the first restcall
},
com.company.android: {
title: foobar,
existingInfo: barfoo
}
}
Обновление: мне удалось заставить код работать, но я думаю, что, возможно, это можно сделать по-другому.
const apps$ = of(apps).pipe(
mergeMap((apps:any) => { //**1**
const appPromise = Object.keys(apps).map((appId) => {
return fetchExternalAppInfo(appId).pipe(take(1));
})
appP.unshift(of(apps));
return of(appP).pipe(mergeAll())
}),
mergeAll(),
scan((acc, curr) => { //**2**
if (!acc) {
acc = curr;
} else {
acc[curr.appId] = Object.assign(acc[curr.appId], curr)
}
return acc
}, null),
map((result) => { //converting to an array which is ordered by title
return _.orderBy(result, 'title')
}),
)
** 1 = Это вернет массив Observable, который должен быть передан непосредственно в mergeAll ().Это правильный способ подписаться и объединить массив Observable
** 2 = Я знаю, что первый Объект, который передается этой функции, является моим начальным значением (appPromise.unshift (из (приложения))).Вот как я могу сохранить старое начальное значение и добавить к нему новое значение.
* ОБНОВЛЕНИЕ 2 *
Это еще одно решение, и я думаю, что этоГораздо лучше: здесь я использую CombineLates для редактирования исходного объекта.
const fetchedApps$ = applist$.pipe(
mergeMap((apps:any) => { //*1
const appPromise = Object.keys(apps).map((appId) => {
return fetchExternalAppInfo(appId).pipe(take(1));
})
return of(appP).pipe(mergeAll())
}),
mergeAll(),
scan((acc, curr:any = {}) => {
acc[curr.appId] = curr;
return acc;
}, {}),
);
const apps$ = combineLatest(of(apps), fetchedApps$).pipe(
map(([a,b]) => {
return _.merge(a,b)
}),
map((result) => {
return _.orderBy(result, 'title')
}),
// * 1 Есть ли другой способ "начать подписку" на массиве наблюдаемыхкроме вызова mergeAll () дважды?