Decorators In Angular
In this article, we will learn what is Angular Decorator and which decorators Angular supports. In our Angular App, we use Angular Decorators in a variety of areas. It's used to decorate components, directives, and Angular Modules, among other things.
Angular Decorators
An Angular Decorator is a function that allows you to add metadata to a class, method, accessor, property, or argument. The decorator is applied with the form @expression, where expression is the decorator's name.
Decorators are Typescript features that are not yet included in Javascript. The proposal stage is currently ongoing.
We need to add the experimentalDecorators to the tsconfig.json file to allow Angular Decorators. This is immediately added by the ng new command.
{ "compilerOptions": { "target": "ES5", "experimentalDecorators": true } }
Creating a new Decorator in Angular
The following code demonstrates how to make an Angular Decorator. The AppComponent class is decorated with the simpleDecorator. There are no counter-arguments.
import { Component, VERSION } from '@angular/core'; @simpleDecorator @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { name = 'Angular ' + VERSION.major; constructor() { console.log('Hello from Class constructor'); } ngOnInit() { console.log((this as any).value1); console.log((this as any).value2); } } function simpleDecorator(target: any) { console.log('Hello from Decorator'); Object.defineProperty(target.prototype, 'value1', { value: 100, writable: false }); Object.defineProperty(target.prototype, 'value2', { value: 200, writable: false }); } **** Console *** Hello from Decorator Hello from Class constructor 100 200
The decorator, as previously said, is a function. It receives the target as an argument, which is the AppComponent.
function simpleDecorator(target: any) { console.log('Hello from Decorator');
We add two new properties value1 and value2 to our AppComponent inside the function.
Object.defineProperty(target.prototype, 'value1', { value: 100, writable: false }); Object.defineProperty(target.prototype, 'value2', { value: 200, writable: false });
We can now use it to embellish our AppComponent.
@simpleDecorator @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent {
We may access the new properties from within the component.
ngOnInit() { console.log((this as any).value1); console.log((this as any).value2); }
Decorator with Arguments
We need to develop a factory function that returns the Decorator function in order to generate a Decorator with arguments.
import { Component, VERSION } from '@angular/core'; @simpleDecorator({ value1: '100', value2: '200' }) @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { name = 'Angular ' + VERSION.major; constructor() { console.log('Hello from Class constructor'); } ngOnInit() { console.log((this as any).value1); console.log((this as any).value2); } } function simpleDecorator(args) { console.log(args); return function(target: any) { console.log('Hello from Decorator'); console.log(typeof target); console.log(target); Object.defineProperty(target.prototype, 'value1', { value: args.value1, writable: false }); Object.defineProperty(target.prototype, 'value2', { value: args.value2, writable: false }); }; }
The decorator function is returned by the simpleDecorator, which takes the args as an argument. The rest of the code is identical to the previous section, with the exception that we use the args to populate the properties.
function simpleDecorator(args) { console.log(args); return function(target: any) {
On the component, we use the simpleDecorator as seen below:
@simpleDecorator({ value1: '100', value2: '200' }) @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent {
List of All Angular Decorators
The following is a complete list of Angular Decorators.
- @NgModule
- @Component
- @Injectable
- @Directive
- @Pipe
- @Input
- @Output
- @Host
- @HostBinding
- @HostListener
- @ContentChild
- @ContentChildren
- @ViewChild
- @ViewChildren
- @Inject
- @Self
- @SkipSelf
- @Optional
We can categorize them into four main groups.
- Class decorators.
- Property decorators
- Method decorators
- Parameter decorators
Class decorators
Class decorators are used to decorating classes. In Angular, Class Decorators include @NgModule, @Component, @Injectable, @Directive, and @Pipe.
@NgModule
The @NgModule Decorator turns the class into an Angular Module and adds the necessary metadata.
@NgModule({ providers?: Provider[], declarations?: Array<Type<any> | any[]>, imports?: Array<Type<any> | ModuleWithProviders<{}> | any[]>, exports?: Array<Type<any> | any[]>, bootstrap?: Array<Type<any> | any[]>, schemas?: Array<SchemaMetadata | any[]>, id?: string, jit?: true })
@Component
Only when we use the @Component Decorator does Angular recognize the class as an Angular Component.
@Component({ changeDetection?: ChangeDetectionStrategy, viewProviders?: Provider[], moduleId?: string, templateUrl?: string, template?: string, styleUrls?: string[], styles?: string[], animations?: any[], encapsulation?: ViewEncapsulation, interpolation?: [string, string], preserveWhitespaces?: boolean, })
@Injectable
The injectable decorator has two functions.
It tells Angular that this class requires a dependency. The metadata required to create the class's dependencies will be generated by the Angular compiler.
Second, we tell the Dependency Injection system how to supply the service using providedIn.
@Injectable({ providedIn?: Type<any> | 'root' | 'platform' | 'any' | null })
@Directive
A class is marked as an Angular directive with the @Directive Decorator. The directives let us change a DOM element's look, behavior, or layout.
@Directive({ selector?: string, inputs?: string[], outputs?: string[], providers?: Provider[], exportAs?: string, queries?: { [key: string]: any;}, host?: {[key: string]: string; }, jit?: true })
@Pipe
An Angular Pipe decorator that adds configuration details to a class.
@Pipe({ name: string, pure?: boolean })
Property Decorators
Property Decorators are applied to the class's properties.
@Input
The input decorator transforms a property into an input property. That is, it is capable of receiving data from the parent component. Property binding is used by the parent component to connect it to a component property. Angular updates the value in the child component whenever the value in the parent component changes.
Input(bindingPropertyName?: string)
@Output
The output property is decorated with the output property. We set it up as an EventEmitter. The data is passed as an argument to the event by the child component, which raises the event. The parent component uses event binding to listen for events and reads the data.
Output(bindingPropertyName?: string)
@ContentChild & @ContentChildren
The decorators ContentChild and ContentChildren are used to Query and obtain the reference to the Projected Content in the DOM. The content that this component receives from a parent component is known as projected content.
ContentChild( selector: string | Function | Type<any> | InjectionToken<unknown>, opts?: {read?: any; static?: boolean;} ) ContentChildren( selector: string | Function | Type<any> | InjectionToken<unknown>, opts?: { descendants?: boolean; read?: any;} )
@ViewChild & @ViewChildren
To Query and retrieve the reference of the DOM element in the Component, use the ViewChild or ViewChildren decorators. ViewChild returns the first matched element, while ViewChildren produces a QueryList of all matching elements. These references can be used to manipulate the component's element properties.
ViewChild( selector: string | Function | Type<any> | InjectionToken<unknown>, opts?: { read?: any; static?: boolean;} )
ViewChildren( selector: string | Function | Type<any> | InjectionToken<unknown>, opts?: {read?: any;} )
@HostBinding
We can use the HostBinding to bind to a property of the host element. The host is an element to which our component or directive is attached. We can use this feature to change the host styles.
@HostBinding(hostPropertyName?: string)
Method decorators
The class's methods are decorated with method decorators.
@HostListener
The HostListener is an application that listens to host events. The host is an element to which our component or directive is attached. We may use HostListener to respond anytime the user interacts with the host element.
@HostListener(eventName: string, args?: string[])
Parameter decorators
The constructor argument of the class is decorated with parameter decorators.
@Inject
@Inject() is a constructor parameter decorator that instructs angular to inject the parameter with the dependency specified in the token. It's a time-consuming method of injecting the dependency.
Inject(token:any)
@Host
The @host parameter tells the DI framework to resolve the dependence in the view by checking injectors of child elements and stopping when it reaches the current component's host element.
@Self
The @Self decorator tells Angular to only look at the local injector for the dependency. The injector that is part of the present component or directive is known as the local injector.
@SkipSelf
The @SkipSelf decorator tells Angular to start searching for the dependency in the Parent Injector and work its way up.
@Optional
The dependency is marked as Optional with the @Optional annotation. If the dependency can't be discovered, it returns null rather than giving an exception.
You can also make your own personal decorations.
Conclusion
In this article, we learned what is Angular Decorator and which decorators Angular supports.
I hope this article helps you and you will like it.👍
If you have any doubt or confusion then free to ask in the comment section.