The constructor is a method in JavaScript and is considered as a feature of the class in es6 .When the class is instantiated it immediately runs the constructor whether it is used in Angular framework or not.So it is called by JavaScript engine and Angular has no control on that.
import {Component} from '@angular/core';
@Component({})
class CONSTRUCTORTEST {
//This is called by Javascript not the Angular.
constructor(){
console.log("view constructor initialised");
}
}
The "ConstructorTest" class is instantiated below;So it internally calls the
constructor(All these happens by JavaScript(es6) no Angular).
new CONSTRUCTORTEST();
That is why there is ngOnInit lifecycle hook in Angular.ngOnInit renders when Angular has finished initialising the component.
import {Component} from '@angular/core';
@Component({})
class NGONINITTEST implements onInit{
constructor(){}
//ngOnInit calls by Angular
ngOnInit(){
console.log("Testing ngOnInit");
}
}
First we instantiate the class as below which happen to immediate runs of constructor method.
let instance = new NGONINITTEST();
ngOnInit is called by Angular when necessary as below:
instance.ngOnInit();
But you may ask why we are using constructor in Angular?
The answer is dependencies injections.As it is mentioned before, constructor calls by JavaScript engine immediately when the class is instantiated (before calling ngOnInit by Angular), so typescript helps us to get the type of the dependencies are defined in the constructor and finally tells Angular what type of dependencies we want to use in that specific component.
The article The essential difference between Constructor and ngOnInit in Angular explores the difference from multiple perspectives. This answer provides the most important difference explanation related to the component initialization process which also shows the different in usage.
Angular bootstrap process consists of the two major stages:
constructing components tree
running change detection
The constructor of the component is called when Angular constructs components tree. All lifecycle hooks are called as part of running change detection.
When Angular constructs components tree the root module injector is already configured so you can inject any global dependencies. Also, when Angular instantiates a child component class the injector for the parent component is also already set up so you can inject providers defined on the parent component including the parent component itself. Component constructors is the only method that is called in the context of the injector so if you need any dependency that's the only place to get those dependencies.
When Angular starts change detection the components tree is constructed and the constructors for all components in the tree have been called. Also every component's template nodes are added to the DOM. The @Input communication mechanism is processed during change detection so you cannot expect to have the properties available in the constructor. It will be available on after ngOnInit.
Let's see a quick example. Suppose you have the following template:
<my-app>
<child-comp [i]='prop'>
So Angular starts bootstrapping the application. As I said it first creates classes for each component. So it calls MyAppComponent constructor. It also creates a DOM node which is the host element of the my-app component. Then it proceeds to creating a host element for the child-comp and calling ChildComponent constructor. At this stage it's not really concerned with the i input binding and any lifecycle hooks. So when this process is finished Angular ends up with the following tree of component views:
MyAppView
- MyApp component instance
- my-app host element data
ChildCompnentView
- ChildComponent component instance
- child-comp host element data
Only then runs change detection and updates bindings for the my-app and calls ngOnInit on the MyAppComponent class. Then it proceeds to updating the bindings for the child-comp and calls ngOnInit on the ChildComponent class.
You can do your initialization logic in either constructor or ngOnInit depending on what you need available. For example the article Here is how to get ViewContainerRef before @ViewChild query is evaluated shows what type of initialization logic can be required to be performed in the constructor.
Here are some articles that will help you understand the topic better:
The constructor is a method in JavaScript and is considered as a feature of the class in es6 .When the class is instantiated it immediately runs the constructor whether it is used in Angular framework or not.So it is called by JavaScript engine and Angular has no control on that.
The "ConstructorTest" class is instantiated below;So it internally calls the constructor(All these happens by JavaScript(es6) no Angular).
That is why there is ngOnInit lifecycle hook in Angular.ngOnInit renders when Angular has finished initialising the component.
First we instantiate the class as below which happen to immediate runs of constructor method.
ngOnInit is called by Angular when necessary as below:
But you may ask why we are using constructor in Angular?
The answer is dependencies injections.As it is mentioned before, constructor calls by JavaScript engine immediately when the class is instantiated (before calling ngOnInit by Angular), so typescript helps us to get the type of the dependencies are defined in the constructor and finally tells Angular what type of dependencies we want to use in that specific component.
The article The essential difference between Constructor and ngOnInit in Angular explores the difference from multiple perspectives. This answer provides the most important difference explanation related to the component initialization process which also shows the different in usage.
Angular bootstrap process consists of the two major stages:
The constructor of the component is called when Angular constructs components tree. All lifecycle hooks are called as part of running change detection.
When Angular constructs components tree the root module injector is already configured so you can inject any global dependencies. Also, when Angular instantiates a child component class the injector for the parent component is also already set up so you can inject providers defined on the parent component including the parent component itself. Component constructors is the only method that is called in the context of the injector so if you need any dependency that's the only place to get those dependencies.
When Angular starts change detection the components tree is constructed and the constructors for all components in the tree have been called. Also every component's template nodes are added to the DOM. The
@Input
communication mechanism is processed during change detection so you cannot expect to have the properties available in the constructor. It will be available on afterngOnInit
.Let's see a quick example. Suppose you have the following template:
So Angular starts bootstrapping the application. As I said it first creates classes for each component. So it calls
MyAppComponent
constructor. It also creates a DOM node which is the host element of themy-app
component. Then it proceeds to creating a host element for thechild-comp
and callingChildComponent
constructor. At this stage it's not really concerned with thei
input binding and any lifecycle hooks. So when this process is finished Angular ends up with the following tree of component views:Only then runs change detection and updates bindings for the
my-app
and callsngOnInit
on the MyAppComponent class. Then it proceeds to updating the bindings for thechild-comp
and callsngOnInit
on the ChildComponent class.You can do your initialization logic in either constructor or
ngOnInit
depending on what you need available. For example the article Here is how to get ViewContainerRef before @ViewChild query is evaluated shows what type of initialization logic can be required to be performed in the constructor.Here are some articles that will help you understand the topic better: