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.

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!

⚡️ FREE eBook: 🔥 ForEach, Map, Filter, Reduce, Some, Every, Find “This book is straight to the point, syntax exploration, comprehensive guide, real-world examples, tips and tricks - it covers all you need “This book is straight to the point, syntax exploration, comprehensive guide, real-world examples, tips and tricks - it covers all you need Todd Motto, author of Exploring JavaScript Array Methods

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!