Recursive calls to Firestore

后端 未结 2 635
滥情空心
滥情空心 2021-01-20 09:14

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

2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-20 09:34

    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.

提交回复
热议问题