# Angular - Custom Structural Directives

I've sometimes asked myself what are `*ngIf` and `*ngFor` in Angular but never dig into it before until I faced a case where none of the knowledge I had about Angular concept at that time (services, validators, guards, interceptors, directives) would give me the answer I needed.

What I wanted to do, was an `*ngIf` like element that I could call in my component to manage my user permissions, something that I would call: `*ifHasPermission`

It's by searching for more details about `*ngIf` that I discovered: **Structural Directives**

## What is this?

Structural Directives are the handyman that change the structure of the DOM by adding or removing elements from it.

They are prefixed with `*` and if you're using Angular I'm sure you know some of them: `*ngIf, *ngFor` are the most well known.

## How to make one?

Let's create our `*ifHasPermission` structural directive.

I want to be able to use this structural directive like so:

```xml
<button *ifHasPermission="user.features.includes('PROFILE')"></button>
```

For each element of my view to be displayed only if the user feature array contains the required element.

Let's begin with the empty shell of a classic `directive` :

```typescript
import { Directive, Input } from "@angular/core";

@Directive({
  selector: "[ifHasPermission]",
})
export class IfHasPermissionDirective {
  
  constructor() {}

  @Input() set ifHasPermission(condition: boolean) {}
}
```

Here nothing complexe a simple `@Directive` decorator with a `selector` param defining the name of your directive (don't forget the `[ ]` ).

Then a class `IfHasPermissionDirective` contains an empty `constructor` and a `ifHasPermission` function.

If you're not familiar with the `@Input set` syntax you can undestand it like so:

* `@Input` : Parent to child data transmission, in our case it means that the component we will use the `ifHasPermission` on will pass some data to our `IfHasPermissionDirective`
    
* `set` : on change, the property will be equal to the new value
    

Now let's add the magic :

```typescript
import { Directive, Input, TemplateRef, ViewContainerRef } from "@angular/core";

@Directive({
  selector: "[ifHasPermission]",
})
export class IfHasPermissionDirective {

  constructor(
    private readonly templateRef: TemplateRef<any>,
    private readonly viewContainer: ViewContainerRef
  ) {}

  @Input() set ifHasPermission(condition: boolean) {
    condition
      ? this.viewContainer.createEmbeddedView(this.templateRef)
      : this.viewContainer.clear();
  }
}
```

Let's break down this code:

In the `constructor` we inject two private elements in readonly.

* `TemplateRef`: represents an embedded template that can be used to instantiate embedded views.
    
* `ViewContainerRef`: represents a container where one or more views can be attached to a component.
    

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">I will talk more about those two classes in another article that I will like to this one, I still have some work to do before explaining them to you in simple words.</div>
</div>

Now in `ifHasPermission()` we use a ternary to say:

```javascript
if(I have the permission){
    "Display the element"
}else{
    "Don't display the element"
}
```

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Don't forget to add your directive in your module to be able to use it</div>
</div>

And TADAM! You now have a structural directive that you can use in all your application to conditionally display or hide the element of your page.
