Difference between Constructor and ngOnInit
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:
- Everything you need to know about change detection in Angular
- Angular’s $digest is reborn in the newer version of Angular
- The mechanics of property bindings update in Angular
The Constructor
is a default method of the class that is executed when the class is instantiated and ensures proper initialisation of fields in the class and its subclasses. Angular, or better Dependency Injector (DI), analyses the constructor parameters and when it creates a new instance by calling new MyClass()
it tries to find providers that match the types of the constructor parameters, resolves them and passes them to the constructor like
new MyClass(someArg);
ngOnInit
is a life cycle hook called by Angular to indicate that Angular is done creating the component.
We have to import OnInit
like this in order to use it (actually implementing OnInit
is not mandatory but considered good practice):
import { Component, OnInit } from '@angular/core';
then to make use of the method OnInit
, we have to implement the class like this:
export class App implements OnInit {
constructor() {
// Called first time before the ngOnInit()
}
ngOnInit() {
// Called after the constructor and called after the first ngOnChanges()
}
}
Implement this interface to execute custom initialization logic after your directive's data-bound properties have been initialized. ngOnInit is called right after the directive's data-bound properties have been checked for the first time, and before any of its children have been checked. It is invoked only once when the directive is instantiated.
Mostly we use ngOnInit
for all the initialization/declaration and avoid stuff to work in the constructor. The constructor should only be used to initialize class members but shouldn't do actual "work".
So you should use constructor()
to setup Dependency Injection and not much else. ngOnInit() is better place to "start" - it's where/when components' bindings are resolved.
For more information refer here:
https://angular.io/api/core/OnInit
Angular Component Constructor Vs OnInit
Important to note that @Input values are not accessible in the constructor (Thanks to @tim for suggestion in comments)