Let’s explore the key differences between the OnInit
lifecycle hook in Angular versus the constructor
that we declare via a TypeScript class.
The difference between the two, or where to put particular logic, has been the source of some confusion for those getting started with Angular - you may have questions such as;
“Do I put this in the constructor?”
“What do I need OnInit for?”
“Can I use the constructor and OnInit for the same thing?”
I’m going to help you answer some of these questions you may be having, and show you the difference between constructors and the OnInit
lifecycle hook, to guide you through making your own decisions when building out your Angular apps.
To better understand the decision we would need to make, let’s understand what a constructor
and lifecycle hook is.
Table of contents
What is a constructor?
The constructor
lives on a JavaScript (ES2015/ES6) class (or a TypeScript class in this case) is a feature of a class itself - it’s not an Angular feature!

🎉 Download it free!
Ready to go beyond ForEach? Get confident with advanced methods - Reduce, Find, Filter, Every, Some and Map.
-
Fully understand how to manage JavaScript Data Structures with immutable operations
-
31 pages of deep-dive syntax, real-world examples, tips and tricks
-
Write cleaner and better-structured programming logic within 3 hours
As an extra bonus, we'll also send you some extra goodies across a few extra emails.
A constructor
is invoked first when a class is being instantiated, which means it’s a good place to possibly put some logic.
class Pizza {
constructor() {
console.log('Hello world!');
}
}
// create a new instance, constructor is
// then invoked by the *JavaScript Engine*!
const pizza = new Pizza();
The main piece here is that the JavaScript engine calls the constructor
, not Angular directly, as in this example - there is no Angular! It’s plain JavaScript.
Constructors in Angular
What about when we are using Angular? In this case, the constructor
is best left for simply ‘wiring things up’, as this is where Angular resolves providers you declare in your constructor, through Dependency Injection:
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({...})
class PizzaComponent {
constructor(
private route: ActivatedRoute
) {}
}
This will bind ActivatedRoute
to the class, making it accessible as part of the component class via this.route
.
The lesson here is that it’s out of Angular’s control when the constructor
is invoked, so we should leave it for merely wiring up purposes instead of attempting to place any initialisation logic here - as Angular has a special lifecycle hook, OnInit
, for this very reason. But before we dive too deep on OnInit
, let’s understand the concept of a lifecycle hook.
What are Lifecycle Hooks in Angular?
Lifecycle hooks are just methods on an object, on a component for example, at key points in time. Some typical lifecycle hooks that ship with Angular include OnInit
, OnDestroy
and OnChanges
. For the complete list of lifecycle hooks, check out the Lifecycle Hooks documentation page.
Want to deep-dive into Angular’s lifecycle hooks? We have an “Exploring Lifecycle Hooks” series covering them all! Start with our guide to OnInit and follow the rest of the series.
A lifecycle hook could give us key insights as to what’s happening with a component, for instance. When the component is created, the OnChanges
lifecycle hook fires first. Secondly, OnInit
, where we now realise our component is ready to go. If our component were to be destroyed, we’d then be able to write some code to slot into the OnDestroy
lifecycle hook - to run some cleanup logic, perhaps.
With this in mind, what does the OnInit
lifecycle hook give us? Let’s explore and gain a better understanding.
OnInit Lifecycle Hook
By adding this lifecycle hook to a component, Angular has full control, unlike the constructor
. Angular will invoke the OnInit
lifecycle hook once it has finished setting the component up.
The way we can use this hook is via an interface, OnInit
, which we simply declare via the implements
keyword (this will create a contract between the class and TypeScript to ensure the method ngOnInit
is present on the class):
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({...})
class PizzaComponent implements OnInit {
constructor(
private route: ActivatedRoute
) {}
ngOnInit() {
// subscribe when OnInit fires
this.route.params.subscribe(params => {
// now we can do something!
});
}
}
This approach also makes unit testing easier, as we could actually invoke the lifecycle hook ourselves. Here’s what technically happens when Angular instantiates our component and invokes ngOnInit
:
const instance = new PizzaComponent();
// Angular calls this when it's ready
instance.ngOnInit();
Differences between constructor and OnInit
To conclude, the ngOnInit
is purely there to give us a signal that Angular has finished initialising the component - and we’re ready to roll.
This initialisation phase includes the first pass at Change Detection, which means any @Input()
properties are available inside ngOnInit
, however are undefined
inside the constructor
, by design.
The differences are subtle, yet important. Now we’ve fully explored the constructor
role, you’re now primed to make the right decision with OnInit
! Using OnInit
gives us a guarantee that bindings are readily available and we can use them to the fullest.
To learn more techniques, best practices and real-world expert knowledge I’d highly recommend checking out my Angular courses - they will guide you through your journey to mastering Angular to the fullest!
It’s also important not to overload your constructor
with initialisation logic, with this in mind and benefits we see unit testing - we’re onto a winner.