A New York Times article in March of 2021 discussed the rapid decline in commercial office space occupancy in Manhattan due to COVID, speculating how the city will never be the same. If we’re lucky…
Now lets define who can do what:
CASL allows to translate such permissions into DSL with help of AbilityBuilder
class:
First of all, lets add our abilities in src/config/abilities.js
file:
Now I need an instance of currently logged in User
. To get a reference to that object, I need somehow to hook into session management logic. As Session
was defined as js-data Mapper
, I can use DataStore
to listen to Session
management events.
As you can see from the code above I listen to 3 events of DataStore
that allows me to understand when Session
is created, destroyed or found and update user abilities accordingly.
Now everything seems ok, but if you try to check abilities on models, you will always receive false
because CASL can’t detect model’s type. We need to teach it by specifying subjectName
option:
Now all good! Lets move on to actual integration with Aurelia templates.
There are 2 ways of how we can add ability checks into Aurelia templates:
I’m going to implement both and later you will understand why. It’s easy to generate binding behavior and value converter using aurelia cli (specify can
as a name for both):
Generated classes I’m going to move into single src/pipes/can.js
because all this is basically a one thing.
In value converter, we just need to inject Ability
instance and use its can
method:
Now lets make this converter to be global. To do this I just need to add a line of code into src/main.js
:
This allows me to bind ability checks in any template with help of if
binding:
But when you test it, it doesn’t work, why? Because Aurelia tracks changes based on used expressions in the binding. The current if
binding has 2 static strings and has no knowledge about rules
array of Ability
instance. Thus don’t know that binding needs to be updated when rules are changed.
It also requires a change in src/config/abilities.js
file:
Now everything works as expected but it’s a bit tedious to write signal: ability-changed
in every binding where we use can
. It’d better to write custom can
binding behavior which hides this complexity. To do that I will injectSignalBindingBehavior
which re-evaluates binding automatically when ability-changed
signal is received. Also I need automatically wrap all expression in can
value converter:
Using this binding behavior, templates looks simpler:
That’s it! 🙂
If you like this article, please consider recommending it. 👏
CASL has complementary packages for major frontend frameworks, check the articles below:
Over emphasized because without action, mindset is useless for getting results. Under, because people think it won’t do anything and is an excuse not to take action — The “just do it” crowd. So they…
Those of an economically right-wing bend, libertarians by definition, will often argue against taxation. They argue that the very idea of taxation is robbery. Not just robbery. But robbery under the…
I have wanted to write novels for as long as I can remember. Books have always been a monumental part of my life as a reader, a collector, and an aspiring author. I read Steinbeck and am in awe of…