I have a Firebase Firestore with \"Components\" as a root collection. Each document (a \"Component\") in the collection may have an array called \"children\", with each ite
You may look at a solution along these lines
// simulates an async data fetch from a remote db
function getComponent(id) {
return of(components.find(comp => comp.id === id)).pipe(delay(10));
}
function expandComp(component: Observable) {
return component.pipe(
tap(d => console.log('s', d.name)),
mergeMap(component => {
if (component.childrenIds) {
return concat(
of(component).pipe(tap(comp => comp['children'] = [])),
from(component.childrenIds).pipe(
mergeMap(childId => expandComp(getComponent(childId)))
)
)
.pipe(
reduce((parent: any, child) => {
parent.children.push(child);
return parent;
})
)
}
else {
return of(component);
}
})
)
}
.subscribe(d => // do stuff, e.g. console.log(JSON.stringify(d, null, 3)))
I have tested the above code with the following test data
const componentIds: Array = [
'1',
'1.1.2'
]
const components: Array = [
{id: '1', name: 'one', childrenIds: ['1.1', '1.2']},
{id: '1.1', name: 'one.one', childrenIds: ['1.1.1', '1.1.2']},
{id: '1.2', name: 'one.two'},
{id: '1.1.1', name: 'one.one.one'},
{id: '1.1.2', name: 'one.one.two', childrenIds: ['1.1.2.1', '1.1.2.2', '1.1.2.3']},
{id: '1.1.2.1', name: 'one.one.two.one'},
{id: '1.1.2.2', name: 'one.one.two.two'},
{id: '1.1.2.3', name: 'one.one.two.three'},
]
The basic idea is to call recursively the expandComp
function, while the looping along the children of each component is obtained using the from
function provided by RxJS.
The grouping of the children within the parent component is provided using the reduce
operator of RxJS, used within expandComp
function.
I have tried initially to look at the expand
operator of RxJS, but I was not able to find a solution using it. The solution proposed by @ggradnig leverages expand
.