Question: Processing Array of Observables with Metadata in Angular
How can I process an array of Observables, such as using forkJoin
, while passing additional metadata for each Observable to be used in the pipe
and map
functions?
const source = {animal: 'cat', fruit: 'apple', color: 'blue'}
const observables = Object.keys(source).map(key => [this.getDataFromApi(source[key]), key])
// Need to resolve only observables[0][0], observables[0][1], observables[0][2] in a special way,
// while preserving observables[1][0], observables[1][1], observables[1][2] for future use in pipe and map
const processedObservable = forkJoin(observables).pipe(
map(items => items.map(item => 'This is ' + item[0] + '(' + item[1] + ')')),
map(items => items.join(', '))
)
processedObservable.subscribe(text => console.log(text)) // For testing purposes
// Expected result: This is your cat (animal), This is your apple (fruit), This is your blue (color)
Description
I have a "source" object containing items. I need to make API requests for each item to get an array of Observables.
Then, I want to process all the received data by using forkJoin
followed by various map
functions within the pipe
.
Please note that direct processing in subscribe is not possible.
Here is a simple example without metadata:
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 output
// Result: This is your cat, This is your apple, This is your blue
In addition to the item data for API requests, I also have metadata associated with each item that needs to be utilized during processing in the pipe
and map
functions.
Though the examples provided show how to ignore metadata or keys, here we focus on incorporating 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 output
// Result: This is your cat, This is your apple, This is your blue
The following example shows how to include metadata but doesn't perform API calls or utilize keys:
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 output
// Result: (animal), (fruit), (color)
The desired outcome is:
// Result: This is your cat (animal), This is your apple (fruit), This is your blue (color)
A solution may involve modifying the forkJoin
call to include both the array of Observables and the metadata associated with each item:
const observables = Object.keys(source).map(key => [this.getDataFromApi(source[key]), key])
Consider using alternative functions like flatMap
or switchMap
if necessary.
Additional Information
The method getDataFromApi
simulates API calls:
getDataFromApi(item) {
return of('your ' + item)
}