What’s the best practice for having an element on a page show up (or not), typically with an IF attribute, but wanting to do this based on the roles of the user?
I know we have the standard way to checking roles:
const isAdmin = await this.authService.hasRole(‘Administrator’);
And I have a Service that loads various user related into, and has the same method hasRole as well.
But trying to put that on an element as an if -is-eval-by this.authService.hasRole('Administrator') | async
seems to hang the UI (browser tab hangs, app manager tab hangs).
What’s the ‘right’ way to do something like this?
Great question. The Async pipe is intended to be used with a subscribable property on a service. “hasRole” is a function on the auth service. If you use that, the async pipe will repeatedly call that function over and over again and cause an infinite loop.
We don’t currently has a subscribable version of hasRole because it would usually be someone else that changes the user’s role. Having immediate update of the client when someone else changes roles on the server would be cool and is technically feasible with things like socket.io but seems more complex than it is worth. The user can just reload the page and they will have a fresh update of their roles.
Thanks, follow up…
First, dynamically changing roles (in some circumstances) is really important, but a good security system would force a logoff of a user in a circumstance that requires a reload of roles, so I guess it’s ok that we don’t have a way to dynamically get role updates.
But, what’s the ‘right’ way then to hide stuff on a page/component based on role? and avoid having the thing called over and over? Is the answer to set a variable in initialize (with the assumption that roles aren’t going to change as discussed) and then just reference that in the page/component elements?
Yes - add a property like “isAuthor”, set that during component initialization by calling the auth service hasRole, and then reference “isAuthor” in the if statements in the template.