Custom Structural Directives in Angular
Published: 2022-06-06 18:02:26


## Custom Structural Directives in Angular

In Angular, Structural directives are the directives that can manipulate the DOM. There are a few built-in structural directives that developers uses in almost every angular applications such as *ngIf, *ngFor, *ngTemplateOutlet, etc.

It’s really amazing how the built-in directives works underneath.

### The ngFor Structural Directive

The ngFor structural directive takes a iterable collection and renders a template each iteration. The template is the element that the directive is applied on.

For example:

![*ngFor example](https://cdn-images-1.medium.com/max/2180/1*9_PWeSgrfpIUnMp5qUPHxQ.png)

Here, debts is a collection with values such as

![debt collection](https://cdn-images-1.medium.com/max/3024/1*RJNSUckf5GvX1rAm4x4JlA.png)

For each of the items in debts the element li will get rendered.

The output for the above code is

![Output intial](https://cdn-images-1.medium.com/max/2000/1*VVpfpP4R1cieEaAb_wn3wQ.png)

So, What happens underneath the compilation of ngFor?

A structural directive encloses the element inside a template fragment and the template fragment into a viewContainer.

The statement

![ngFor debts statement](https://cdn-images-1.medium.com/max/2176/1*tlUaY7V6hRev81iC528ICg.png)

gets compiled into this

![ngFor debt compiled statement](https://cdn-images-1.medium.com/max/2000/1*9b1pq8q8DVvQZRr6yNjxzg.png)

In simple terms, The ngFor directive gets the collection and renders the templates with specifying their each context. 
Each context contains index, $implicit(the particular value of the collection item) and a few other values.

### Let’s modify the ngFor directive

Let’s extend the ngFor directive and develope another feature which is filtering.

We want to do something like this

![filter feature in the directive](https://cdn-images-1.medium.com/max/2000/1*TewCXEhfewPJFmEBcJ7vRw.png)

Where myFilter is

![myFilter method](https://cdn-images-1.medium.com/max/2000/1*KpFBY0bfoJMLVJlJM4XI3w.png)

We are going to create a directive called ngForIf
>  Specifying it’s selector

![directive selector](https://cdn-images-1.medium.com/max/2000/1*exq3IXZbHKbaQtQUgGbLaw.png)
>  Let’s extend the existing NgFor directive

![ngForOfIf member](https://cdn-images-1.medium.com/max/2800/1*IzNjGVd3AGOrPjFZAXH9WA.png)
>  We need to create our own alternative of ngForOf member. Where we’ll store the iterable collection and use it for filtering. As the _ngForOf member from the NgFor class is private, We can only set a value to it.

![_ngFor alternative member](https://cdn-images-1.medium.com/max/2000/1*nCZ4C9op6Y4GQytzV2gc8g.png)
>  Creating the setter for it

![_ngForIfOf setter](https://cdn-images-1.medium.com/max/2000/1*lV91zUkfumHg4iQp0F2q2Q.png)
>  Implementing our ngDoCheck lifecycle hook and calling the ngDoCheck of ngFor class

![ngDoCheck lifecycle hook](https://cdn-images-1.medium.com/max/2000/1*jICehm2cJ9dLemD3EE1pEA.png)
>  Now, To implement the filtering feature, we will create a predicate type for it

![predicate type for filter](https://cdn-images-1.medium.com/max/2000/1*shSJXq5VwXh7S8ItvSLidg.png)
>  Member for storing the filter method

![filter member variable](https://cdn-images-1.medium.com/max/2000/1*2SV_XuqRmjQMBLdnr3tl4w.png)

And finally the setter for the filter. Here, we are checking the availability for _ngForIfOf reference and assigning the filtered values to the ngFor setter of NgFor class.

![filter setter](https://cdn-images-1.medium.com/max/3000/1*z9GKQumxDrj4X9UC4NxddQ.png)

Don’t forget to provide the instances to the super contructor

![constructor](https://cdn-images-1.medium.com/max/2764/1*1XrTZD46QrPTzECKny9r5w.png)

Now we can use our custom structural directive with a filter like this.

![template file with custom directive](https://cdn-images-1.medium.com/max/2768/1*d2JLie1xZG-uj6z9mmmbwQ.png)

Output using the ngForIf Directive

![Output after filtering feature](https://cdn-images-1.medium.com/max/2000/1*C7TqCiWZ8U0YAR3dZvOGnQ.png)

You can find the source code at given link: [https://stackblitz.com/edit/angular-ivy-uoqa3h](https://stackblitz.com/edit/angular-ivy-vwlxuy)