1

One of my components gets an array of items. Each item has a permission, which will be checked by a rest call based on the user role. If the user is permitted for the item, it can be displayed.

So I came along with this approach:

ngOnInit(): void {
  for( let tile of this.tiles ) {
    this.permissionCheckService.isUserPermitted( tile.name ).subscribe( 
      isPermitted => tile.show = isPermitted
    )
  }
}

But this solution introduces a new variable "show". Maybe it would be even better if the items, which should not be displayed, will be removed from the array?

Next step should be to implement a loading indicator. This indicator should be removed, if all requests are finished. But my problems starts here. I think I have to combine all observables, but i don't know how to do it.

Here is a working example: https://stackblitz.com/edit/angular-wfjj5n-horatl?embed=1&file=src/app/alert-basic.ts

2 Answers 2

1

Hiding/showing the loading indicator can be done with one simple boolean flag that's set to true/false on the beginning/completion of the stream. For that, of course, you need to have one stream, so forkJoin or combineLatest are your friends. Also, you can put the result array in a separate stream, to keep with the reactive/immutable paradigm. Something like

  constructor(private permissionCheckService: PermissionCheckService) {}

  ngOnInit(): void {
    this.isLoading = true;

    this.shownTiles$ = this.checkPermissions().pipe(
      map(this.filterTiles),
      tap(() => (this.isLoading = false))
    );
  }

  checkPermissions = (): Observable<boolean[]> =>
    forkJoin(
      this.tiles.map(tile =>
        this.permissionCheckService.isUserPermitted(tile.name)
      )
    );

  filterTiles = (booleanFlagsArr: boolean[]): any[] =>
    this.tiles.filter((tile, index) => booleanFlagsArr[index] === true);

Here's a stackblitz:

https://stackblitz.com/edit/angular-wfjj5n-f7aht4?file=src%2Fapp%2Falert-basic.ts

Sign up to request clarification or add additional context in comments.

1 Comment

thank you very much, great answer! But I have forgotton one detail. Not every item must have a permission. For items which don't have any permission, the service shouldn't be called. I've forked your stackblitz: stackblitz.com/edit/angular-wfjj5n-jkhre6?embed=1&file=src/… . Also I've added the new param "permission" to a tile. Maybe you can help me again?
1

Yopu can use forkJoin to subscribe to an array of calls. Then filter by response

forkJoin(
  this.tiles.map(x => this.permissionCheckService.isUserPermitted(x.name))
).subscribe((res: any[]) => {
  //if you want store in an auxiliar variable
  this.tilesValid = this.tiles.filter((x, index) => res[index]);
  //or
  //this.tiles = this.tiles.filter((x, index) => res[index]);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.