Session.props.auth.user.roles dropdown

Hi
I'm trying to set up a dropdown that displays IdP's roles.

This is the startup script:
image

It works on the Client, but when I open the session in the browser, the options are not displayed.

image

Could someone help me?

On the dropdown, props.options.

Put a binding on this with some expression, like now(10000) and put this script in the script transform. Though I would have it just as options instead of self.props.options and then return this list

1 Like

Is anyone actually logged into the browser session?

I do agree that a binding with some of your code moved into a transform is better than this onStartup approach, though you don't need the now(10000) piece. Bind against self.session.props.auth.user.roles, then use this transform:

def transform(self, value, quality, timestamp):
	roles = [{"label": role, "value": role} for role in value]
	if len(roles) == 0:
		placeholder = "User has no roles."
	else:
		placeholder = "Select role..."
	self.props.placeholder.text = placeholder
	return roles

1 Like

Actually, I'm going to recommend moving the placeholder logic into a change script on Dropdown.props.options. In general, it's bad practice to write to props within a transform; transforms should only be used to manipulate the binding value into some expected format.

3 Likes

It works

Thanks

Is there a reason it's considered bad practice to read the props in a transform?

Reading props is fine. Writing props can be troublesome for a couple of reasons.

  1. It is next to impossible to identify where exterior writes to a value are coming from. Suppose prop "A" is changing value but is has no binding. You first area to investigate will be scripts, but bindings don't always have scripts, so they're not likely to be the first place you look.
  2. A binding on prop "X" is supposed to do something to the value coming into prop "X" - not manipulate some other value. If some other value should change when "X" changes, that value should do so with a binding (or be done as part of a change script).
  3. Bindings should be as performant as possible because your goal should be to populate prop "X" with whatever value as quick as possible. Updating other properties should happen after completion.
  4. It can lead to infinite loops. Suppose you have a binding for prop "X" which looks at prop "Y". Within the transform of "X", you write to "Y" - which causes X to evaluate again.
5 Likes

And sometimes, quite handy. Expression bindings and expression transforms subscribe to every property you use, and will retrigger the binding for any of them.

A script transform gives you the opportunity to monitor one or more items for changes (the part before the transform, whatever it may be), then capture the values of properties and tags at just that moment, without subscribing to the latter.

2 Likes

For this case, isn't it more efficient to go for an onClick event? Then, populating those Dropdown.props.options each time you click on it.

Thinking of dropdowns as form elements, which the user may have on screen but may not even use/click on... Being subscribed to them doesn't seem very efficient.

Requiring a click doesn't work as well as you would think.

  1. Suppose a desktop user is indeed treating the page as a form. There's a good chance they could be tab-ing through inputs. If populated through an onClick Event, the field would never have the data needed.
  2. Use of an onClick Event would lead to a bad/jarring display of the dropdown because the options will display immediately on user click, but the browser tab has only just sent the request for the relevant data. The result is the user is displayed an empty set of options for at least a little bit before the data is finally populated, resulting in a re-render of the options.
  3. There's a chance the Dropdown might be interacted with multiple times during a session. In this scenario, the binding would be far more performant/efficient, as the binding would only execute on the initial View/Page load or when the user's roles changed.

Bindings are far more efficient than you probably think. While it might be true there's a lot to do during the initial loading of a page, bindings against data which doesn't regularly update should have negligible performance impact.

3 Likes

Good points, thanks!

1 Like