I have a type temperature, for example:
type Temperature = {
source: "Sensor A",
value: number,
}
And an observable emitting arrays of this type
temperatures$:$rxjs$Observable<Array<Temperature>>
Now I want to Perform a side effect (api call) for each of the temperature objects and append the result of those calls to the objects (when all are resolved), so a new observable would emit:
type TemperatureWithResult = {
...Temperature,
result: {
success: boolean,
message: string
}
}
temperaturesWithResult$:$rxjs$Observable<Array<TemperatureWithResult>>
So what I want in temperaturesWithResult is not to emit the temperature objects with the promises (resulting from the api calls) appended, but the actual results resulting from resolving those promises, so I have given a stab at this problem in the following way:
export default
temperatures$: rxjs$Observable<Array<Temperature>>,
): rxjs$Observable<Array<TemperatureWithResult>> => {
return temperatures$.flatMap(
temperatures => {
return new Promise(resolve => {
const promisedResults = temperatures.map(temperatureObject => {
const promisedResult = apiCall({
temperature: temperatureObject.temperature,
});
return {
...temperatureObject,
result: promisedResult, // this is a promise!
};
});
const promises = spreadPromised.map(s => s.result);
Promise.all(promises).then(results =>
resolve(
promisedResults.map((promisedResult, i) => ({
...promisedResult,
result: {
success: true, // to simplify
message: results[i], // I update it with the actual result
}
})),
),
);
});
},
);
But this is not very readable, and there must be a simpler way.