Expression Efficiency for Nested Statement(s)

I am testing filtering certain views based on user roles that i created. I would like for my test view to only be visible if the user role is “Admin” or “Provider.”

I initially tested based on the Provider role. When that filter was active, I as an Admin was no longer able to see the view, but the doctors confirmed they could.

I now want to make sure that I am always able to see things, so I want to add the Admin role. Here’s what I came up with.

OR(
CONTAINS(Current_User[Role],"Admin"),
CONTAINS(Current_User[Role], "Provider")
)

This works just fine, but what i would like to know is if there is a more efficient way to write this expression so that i only use one statement to see if the user role is any of the ones i want to see the view. Something like

If Current_User[Role] is Admin or Provider or Registration, show this view.

Thanks

  • CONTAINS() is for matching text values, with lists you should instead use IN().
  • Current_User[Role] is not a single value, this is a list of all Roles in the Current_User table, hence your expression is not doing any filtering; it will just always match. You need to use SELECT() with ANY() to extract the Role value that corresponds to the user.

Probably should clarify, Current_User is a slice created based on this guide:

https://www.googlecloudcommunity.com/gc/Tips-Tricks/How-to-conform-your-app-around-WHO-is-using-the-app-Current-User/m-p/347947

Which seems to target the current user and find them in the user table. So theoretically, it is not a list but somehow pulling a singular value. I may need to re-read that article a few times but it seems to be working, i just want to try to make the expression more efficient. In my testing, when i removed Admin from the expression, i could no longer see the view, but the Provider role could. What am i missing here :thinking:

In that case, if this is a single-value list, then it’s OK. Just use IN() like this:

IN( ANY(Current_user[Role]), LIST(“Admin”, “Provider”, “Registration”) )

1 Like

awesome, thank you!

1 Like

Can you explain the difference between using ANY and not using ANY? The plain english without the ANY expression says:

(Current_User[Role]) is one of the values in the list (LIST(
...."Admin"
...."Provider"))

but if I add ANY, it says this:

(One randomly chosen value from this list (
....Current_User[Role])) is one of the values in the list (LIST(
...."Admin"
...."Provider"))

what’s throwing me here is the “one randomly chosen value from this list” part. I’ll re-read the documentation for ANY() and see if something clicks for me.

You have a single-element list and you want to extract the value of this element. Even when a list contains one element it is still a list. ANY() is used in this case to remove the list data type, so when your expression for example expects a text it is not faced with a list input.

2 Likes

thank you

and if a users have multiple roles, i would use Select instead of Any? Is this correct?

This expression seems to work as well, just trying to understand what it does differently than an Any statement. My apologies for being dense on this :disappointed_face: I just want to make 100% sure i fully understand instead of copy/pasting answers.

IN(SELECT(Current_User[Role],true),LIST("Admin","Provider"))
1 Like

Well done :slightly_smiling_face: you should be proud instead of apologetic about your learner attitude! And for this, before answering your question, please read this excellent guide carefully:

FAQ: FILTER(), LOOKUP(), MAXROW(), MINROW(), REF_R… - Google Cloud Community

Now for your other question, what if users could have multiple roles?

First, generally speaking, this is not a good IT practice.

Secondly, there should be no problem devising the appropriate expression at all, but before that, what would be exactly your logic? Do you want to match ALL roles? only ONE of them? what is precedence among the different roles? Once you have this defined, we can write the corresponding expression.

1 Like

it’s going to take me a bit to read through that page, as I want to read and try to understand ALL of it, even if i think i know some of it :slightly_smiling_face:

As for the multiple roles thing, it can be handy. Let’s say person A needs access to the Patient Registration app (when i say app in this case, it s a View). Person A is also a member of the TCM (transitional care management) team, so she also needs access to the TCM app. I would flag her user account with both roles.

So i would ideally want my filter to check the list of user roles for the current user, and if the Registration role appears in the user’s role value, whether it be a single entry or one of multiple for that user, then that user is allowed to see apps or view associated with their roles.

My plan is to use this system to have a singular app with many views, but the views be limited based on roles to prevent the end user from having a cluttered app full of things they wont use. If that user needs access to another view later, i would be as simple as me logging into the USer Management app i created and clicking another option in the Enum List for that user’s role(s)

To me, this is more “elegant” and manageable than making multiple applications, since they all rely on the same common data. Makes more sense to bake role-based views into a singular app, since i can’t easily copy views and expressions into another app without doing a full clone and deleting what i don’t want from the new app.

This is a fairly-standard requirement, and the correct, industry-standard practice to implement it is to create access groups. Each access group will have a list of roles, and each user will be a member of only one access group.

2 Likes

this makes sense. Would definitely make things more manageable as things continue to grow out of control. That way, I only have the app checking for group instead of a specific role.

More to think about :slightly_smiling_face:

1 Like