Short explanation
How to process an array of Observables (for example in forkJoin
) with passing some data for each Observable which I need to use in pipe
&map
?
const source = {animal: 'cat', fruit: 'apple', color: 'blue'}
const observables = Object.keys(source).map(key => [this.getDataFromApi(source[key]), key])
// resolve only observables[0][0], observables[0][1], observables[0][2] in magic way,
// but preserve observables[1][0], observables[1][1], observables[1][2] for future use in pipe&map
const processedObservable = forkJoin(observables).pipe( // ???
map(items => items.map(item => 'this is ' + item[0] + '(' + item[1] + ')')), // this doesn't work
map(items => items.join(', '))
)
processedObservable.subscribe(text => console.log(text)) // subscribe only for test
// expected result: this is your cat (animal), this is your apple (fruit), this is your blue (color)
Long explanation
I have some "source" (array or object of items). I need to request for every item to API, so I get array of Observables.
Next, I want to process all received data, so I use forkJoin
and process data in pipe
and several map
s.
I can't process data in subscribe directly.
Here is the simple example:
const source = ['cat', 'apple', 'blue']
const observables = source.map(item => this.getDataFromApi(item))
const processedObservable = forkJoin(observables).pipe(
map(items => items.map(item => 'this is ' + item)),
map(items => items.join(', '))
)
processedObservable.subscribe(text => console.log(text)) // test
// result: this is your cat, this is your apple, this is your blue
But besides data of items for API requests I have metadata of items which I have to use during processing in pipe
& map
.
Here is the example with representative source, but here I don't use metadata of items (result is same as above). I ignored metadata:
const source = {animal: 'cat', fruit: 'apple', color: 'blue'}
const observables = Object.keys(source).map(key => this.getDataFromApi(source[key]))
const processedObservable = forkJoin(observables).pipe(
map(items => items.map(item => 'this is ' + item)),
map(items => items.join(', '))
)
processedObservable.subscribe(text => console.log(text)) // test
// result: this is your cat, this is your apple, this is your blue
Here is the example with representative source, but here I ignored keys and API calls, but I process metadata of items:
const source = {animal: 'cat', fruit: 'apple', color: 'blue'}
const observables = Object.keys(source).map(key => of(key))
const processedObservable = forkJoin(observables).pipe(
map(items => items.map(item => '(' + item + ')')),
map(items => items.join(', '))
)
processedObservable.subscribe(text => console.log(text)) // test
// result: (animal), (fruit), (color)
I want to get this result:
// result: this is your cat (animal), this is your apple (fruit), this is your blue (color)
In some of this way in pipe
&map
:
map(items => items.map(item => 'this is ' + item.apiValue + '(' + item.key + ')')),
or:
map(items => items.map(item => 'this is ' + item[0] + '(' + item[1] + ')')),
But I don't know how to pass array of observables and metadata to forkJoin
, some of this array of observables with metadata:
const observables = Object.keys(source).map(key => [this.getDataFromApi(source[key]), key])
Maybe should I use different function, for example flatMap
or switchMap
?
Additional info
Method getDataFromApi
for simulate API calls:
getDataFromApi(item) {
return of('your ' + item)
}