Decorators in Typescript and Angular

5 minute read

Decorator in Typescript and Angular

Decorator is a concept in Typescript that can be used to annotate a class or it's members. Decorator also enables meta programming where one can collect as many meta data as required during run time.

If you are coming from Asp.Net background like I do then you might be aware of Action Filters. Action filters in Asp.Net MVC Framework are also example of decorators.

Decorator in Typescript is nothing but a function and I will explain more about decorator below.

Decorator Philosophy

Decorator is an Aspect Oriented Programming paradigm. Where we modularize and define cross-cutting functionalities and hence achieve a strong Separation of Concerns. cross-cutting concerns are like logging, applying transactions, validations etc. It is a good design practice to keep our business logic code separate from other infrastructure or cross-cutting related code. And decorators are great tool to separate them in independent reusable libraries.

Decorators are inspired by Decorator Design Pattern. Decorator is also used to collect metadata at run-time and hence enables meta-programming.

Why should I use Decorator

forest trees marked with question marks

Even though Decorators are experimental feature in Typescript. It is wisely and widely used in many JavaScript frameworks like Angular and NgRX. I believe below are the main motivation behind Decorators and you should also start thinking to use Typescript Decorator in your code.

  • Collect meta data about class or class members.
  • Separate cross cutting concerns like logging
  • Remove code duplicate, repetition and redundancy anti pattern from code.

In Angular Framework there are predefined decorators like Component, Directive, Input, Output, HostListener etc. Angular has created these decorators to keep the redundant and boring task done separately by the Angular Team itself. Therefore, the consumer or Angular Framework does not need to worry about these implementations and  they just focus on business logic. Like Component decorator collects the metadata about selector name, html file path, CSS path and many more information. Under the hood Component decorator does few important tasks that is required for each component in your project, that is very repetitive work like getting HTML file applying CSS on it, Creating custom element with the selector name and rendering it on DOM. All of these tasks are not rocket science however, it is needed for every component and something can be done very easily by decorator function.

Decorator Real World Example

girl decorating the Christmas tree

I want to explain decorator work by giving practical example. Many of us might have worked with personal Advocates. How advocate works ? When you assign advocate for your case then this how coordination between you and your advocate happens:

  • Any call or request coming from Court for you first goes to your advocate.
  • Advocate does preliminary work on your court request and then he asks you to do the work just needed for you like putting your signatures, handing over personal docs etc.
  • Once you are done with your work then advocate sends the respond back court and does further required work for court request on behalf of you and be prepared for next request.

There are many specialized Advocates who are famous for their special works like marriage certificate, crime, insurance etc. These Advocates keep doing some redundant and repetitive works for their clients. So that their clients remain happy and they just do their specific needed job only. Lots of ceremonial work and preparations are done by Advocates.

I know I have given long story :) some of you might think I am Advocate? By the way I am not an advocate! However, this example comes in my mind whenever, I think about Decorators.

Decorator Function in Typescript and its Explanation

In typescript Decorator function is typically written by just simple function which receives 3 parameters like target, propertykey and descriptor

 
function (target: any, propertyKey: string, descriptor: PropertyDescriptor){
}

https://gist.github.com/roopkt/ff673512f854e77a7dab6231d528438a

Decorator Example in Typescript

Decorators work very similar to Advocates like I explained above. Decorators can be applied on class and it's class members only. As of now in Typescript you can not apply decorator on any function, it has to be class or its members. Decorator is a function in Typescript and while applying decorator we have to pre┬Ěpend decorator by `@` symbol. Take below example depicted in picture, LogMethod is a decorator which you have applied on Calculator's add method.

logmethod-decorator-typescript and angular

Suppose we created a decorator to log before and after class method called. Then we can create `LogMethod` decorator and apply on each method of class where we desire to log. In above diagram whenever `add` method of the calculator class will be called then first `LogMethod` function will be called. `LogMethod` will first do logging before calling actual function. Then decorator will call actual function and get the result. Also decorator will log the result of execution and then will return the result. So you can see how decorator can do logging task very simply. You just need to apply @LogMethod decorator on add function of the Calculator class.  Here is the code for LogMethod decorator.  This is an example of method decorator.

https://gist.github.com/roopkt/91bf8284407bc9289810de61da57cf20

Here is the code how you can apply LogMethod decorator on add method of Calculator Service in your Angular App .

https://gist.github.com/roopkt/a4f5eaf7a2192ebc3009ce099809931c

Decorator Example in Angular App

As I already mentioned decorators are widely and wisely used in Angular. There are many built in decorators. Like in NgRx Library very famous decorator is @effect .

I already explained you how you can create method decorator and apply either in vanilla Typescript class or it could be a service class of Angular App. Now I will explain you how you can create and constructor decorator that you can use in your Angular App.

Imagine you want to aromatically unsubscribe all of your RxJS subscriptions in your component.  Sometimes we forget to unsubscribe RxJS subscriptions and hence our angular app becomes very slow because of memory leak issues. Therefore, in order to help ourselves we will create custom decorator and use it on component class. There are various ways to unsubscribe RxJS subscriptions. However for the sake of understanding decorator we will try to achieve this functionality by creating our own custom constructor. I personally love constructor decorators because, it is very powerful such that it can intercept any public method of the target class and apply decoration on it. Here is my code for autoClearSubscriptions decorator.

https://gist.github.com/roopkt/cd1d6798d60a7253e1242e66bf4fdc95

Now its time to apply our custom decorator on our angular component. Here is the code for that.

https://gist.github.com/roopkt/6710d618ff1b0ac033c30570d37490ac

Conclusion

I did not go more deep on decorator function and its parameters passed by Typescript. Because, it will become boring to you. However, if you really think I should explain my code as well then please feel free to write in comment box. I will be happy to see your comments and I might write explanation to my code as well till than Happy Coding and Bye Bye!

References

Decorators Typescript Documentations

Comments