Reusable Directive For Authorisation in Angular, avoid *ngIf!
In this article I’d be talking about how to create a Reusable Directive in Angular for Authorisation purposes.
One of the most common requirements that I see in UI designs is the role based access control. Controlling the display of HTML components on the basis of roles and permissions fetched from the backend.
How many times have we used *ngIf
directive with a really long conditional statement on a HTML Element to show/hide it from the view?
I’d be showing you why and how you can avoid using *ngIf
directive.
User Permissions
First step is to fetch user Permission from a backend API, for now we can declare a static object in our service. Permission is basically an array of strings.
Now, create a permission-service.ts
which allows us to set a new user and to subscribe to changes on our authenticated application user.
We need *ngIf, right?
We can now create a directive that takes the permissions of the currently authenticated user and shows/hides them appropriately. In practice, a custom *ngIf
directive, *ngIf
has a *
in front, which is a special syntax within Angular, denoting a so-called structural directive.
Normally, what we do is apply *ngIf on the HTML component to show/hide it on the basis of a certain condition, for example —
But now let’s suppose you have 100 other HTML components with completely different conditions, you’d have to take care of the putting this long conditional for each of the component, which becomes tedious eventually.
What is a Directive?
An Attribute directive changes the appearance or behavior of a DOM element.
In layman terms, it’s a a piece of code that you add on your HTML components to run a reusable piece of code
There are three kinds of directives in Angular:
- Components — directives with a template.
- Structural directives — change the DOM layout by adding and removing DOM elements.
- Attribute directives — change the appearance or behavior of an element, component, or another directive.
How custom directive helps?
We can create a custom directive which would basically handle all the conditional and business logic instead of putting logic in *ngIf
, it definitely improves the readability and maintainability of the code.
In this directive we are passing the accepted values from the HTML component to the directive as an @Input.
variable which then gets passed to the decideView()
function to put decide business logic.
See, how we shifted responsibility of the business logic from *ngIf
to a custom directive. Every time we just have to pass a list of accepted permissions on HTML component.
To Disable the component
Here, we are using ViewContainerRef to create a new Embedded View by using the templateRef instance that the directive gets and we are adding to the current view. After that, we can change attributes and properties of the HTML Element and all the changes will be visible to you. Here, we are setting the disabled
property to true
to disable the component.
To Enable the component
Here, we are doing the same steps but just setting the disabled
property to false
. Also, make sure to always clear the Container using this.viewContainerRef.clear()
before creating the new element to avoid having to HTML elements.
You can find all the code here,