Linked Questions

Popular Questions

I need to filter a recursive array of objects. Each object represent a webapp route/url. This url can be limited to a certain role (permission=true|false) or not, and each url can have child urls ... recursively.

EDIT: The complicated part is that the filtering needs an asynchronous function call (I have that specific need in my project). That's why I tried to do it with RXJS but I could have done it with standard array functions + async/await...

I also took this opportunity to learn some more rxjs, that's why I want a rxjs-oriented answer (and this it deals with async, it's a good way hu?). Thanks

Having this array :

[
      {
        id: 'level 1.1',
        permission: true,
        children: [
          {
            id: 'level 2.1',
            permission: false,
            children: [
              {id: 'level 3.1'}
            ]
          },
          {
            id: 'level 2.2',
            permission: true,
            children: [
              {id: 'level 3.2'}
            ]
          }
        ]
      },
      {
        id: 'level 1.2'
      },
      {
        id: 'level 1.3',
        permission: false
      }
    ]

I need to filter it to have an output like (keep only entries where permission is absent or truthy :

[
      {
        id: 'level 1.1',
        permission: true,
        children: [
          {
            id: 'level 2.2',
            permission: true,
            children: [
              {id: 'level 3.2'}
            ]
          }
        ]
      },
      {
        id: 'level 1.2'
      }
    ]

What I tried works without the recursion (commented code), So the first level is filtered successfully, but I don't know how to add the recursion :

// simplified ASYNC filter function
promiseMe(x) {
    return Promise.resolve().then(() => {
      return x.permission === undefined || x.permission === true
    });
}

// recursive function
const recursive = arr => {
    return from(arr).pipe(
        mergeMap(entry => from(this.promiseMe(entry)).pipe(
            tap(y => console.log(y)),
            filter(Boolean),
            mapTo(entry),
            tap(console.log),
            mergeMap(item => {
                // here I'm lost
                // I need to affect the result of my async recursive function to item.children : 
              /*return recursive(item.children).pipe(
                  tap(res => {
                    console.log('RES', item, res)
                    item.children = res;
                  })
                );*/

                return of(item);
            })
        )),
        toArray()
    )
};

// main call
recursive(arr).subscribe(x => console.log('finally', x, JSON.stringify(x)))

FIDDLE here : https://stackblitz.com/edit/angular6-rxjs6-playground-idysbh?file=app/hello.component.ts

Related Questions