I have a collection that looks like this
[
{
count: 123,
description: 'some description',
articles: [
{...}
]
},
{
count: 234,
description: 'some description',
articles: [
{...}
]
}
]
Each object in the collection has a collection of articles. What I need is to apply the description
to each article object in the respective collection in each element of the primary collection. I also want to end up with a flat array containing only articles. Clearly I'm using mergeMap
incorrectly, but I'm not sure how to do it.
I have tried this
json$.pipe(
// Filter out empty arrays
filter(section => section.count > 0),
// Apply the descriptions
map(section => section.articles.map(a => (Object.assign(a, section.sectionName)))),
mergeMap(x => x.articles)
).subscribe(x => console.log(x));
But the articles do not have the description
property in them, and it's not a flat array of articles. I've tried a few things but I'm unsure how to proceed
You only need to concatMap
the outer observable, after adjusting each article.
const { Observable } = Rx;
const { map, concatMap, filter } = Rx.operators;
const json$ = Observable.from([
{
count: 123,
description: 'some description 123',
articles: [
{id: 1},
{id: 2},
]
},
{
count: 234,
description: 'some description 234',
articles: [
{id: 3},
{id: 4},
]
}
]);
const withDescription$ = json$.pipe(
filter(({count}) => count > 0),
concatMap(
({articles, description}) => Observable.from(articles).map(a => ({...a, description}))
)
);
withDescription$.subscribe(console.log);
<script src="https://unpkg.com/@reactivex/rxjs@^5/dist/global/Rx.min.js"></script>
If you don't need any special behavior on the inner observable, you could simplify to:
const withDescription$ = json$.pipe(
filter(({count}) => count > 0),
concatMap(
({articles, description}) => articles.map(a => ({...a, description}))
),
);