Difference between Constructor and ngOnInit in Angular

AJIL ANTONY | January 06, 2023

Difference between Constructor and ngOnInit in Angular

This blog explains the differences between the constructor inside a TypeScript class vs OnInit and how to make the best decision. If you're just getting started with Angular or have been using it for a long, you might have concerns like these:

Should I bind data and inject dependencies into the constructor? When does ngOnInit be used? What distinguishes a constructor from OnInit in Angular?

I'm here to address those questions because they are valid. Before we start, it's essential to understand that a constructor is not an Angular feature.

Before moving on to the ngOnInit lifecycle hook, let's discuss constructors.

What is a Constructor?

A constructor is a unique method that is called each time we build a new object. In general, it is used to initialize the members of the class. It is not an Angular feature, but rather an attribute of the class (typescript), a principle in object-oriented design.

The purpose of a constructor will be clear to you if you have experience with object-oriented programming.

When a class instance is formed, a constructor is called first:


    class Pizza {
        constructor() {
            console.log('Hello world!');
        }
    }
        
    // create a new instance, constructor is 
    // then invoked by the *JavaScript Engine*!
    const pizza = new Pizza();
    

Constructors in Angular

When using Dependency Injection, we give dependencies using constructors, which are important in Angular. When a class is formed, Angular examines the Constructors and searches for providers that match the types of arguments in the Constructors. They are then bound to the class after being located.

You probably did something similar, injecting a different class into the constructor:


    import { Component } from '@angular/core';
    import { ActivatedRoute } from '@angular/router';
    
    @Component({...})
    class PizzaComponent {
        constructor(
            private route: ActivatedRoute
        ) {}
    }
    

By doing so, ActivatedRoute will be bound to the class and accessible through the component class's this .route method.

A constructor, in my opinion, is where you should wire up your dependencies and leave it as simple as possible. It is more difficult to test the constructor because Angular does not directly call it.

The addition of the ngOnInit lifecycle hook, which fires as soon as the Angular component is prepared, addresses the fact that Angular has no control over when this constructor is called.

A class's lifecycle hooks are merely methods that define significant moments in time. OnInit, OnDestroy, and Changes are a few of the lifecycle hooks offered by Angular.

A quick fact for you before we continue: the OnChanges lifecycle hook is called first when an Angular component is built.

The OnInit hook is the following lifecycle hook to be called. What does the OnInit lifecycle hook offer us and when should we use it because of this?

OnInit Lifecycle Hook

Angular components can expand in size and complexity, which frequently necessitates the injection of several dependencies, the declaration of properties, and the binding of observables. A constructor would be the best location for injection but not to handle the wiring. Angular calls the lifecycle hooks throughout the change detection cycle but not the constructor until after the component tree has been assembled.

This is where ngOnInit comes in. After importing the OnInit interface and utilizing the implements to provide us with some type of safety, we can declare ngOnInit as a method:


    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!
            });
        }
    }
    

Unit testing is made simpler by this method because we have control over the lifecycle hook. The ngOnInit lifecycle hook is the ideal location for adding more intricate logic and initializing the component.

What actually occurs when Angular instantiates the component and calls ngOnInit is as follows:


    const instance = new PizzaComponent();

    // Angular calls this when it's ready
    instance.ngOnInit();
    

Wiring up observables, communicating with services, and making any necessary requests are all easily accomplished with the ngOnInit lifecycle hook.

Another incredibly significant feature of ngOnInit is that Angular calls it precisely when the component's @Input() properties are prepared:


    @Component({...})
    class PizzaSingleComponent implements OnInit {
        @Input() pizza: Pizza;
    
        constructor() {
            console.log(this.pizza); // undefined
        }
        
        ngOnInit() {
            console.log(this.pizza); // { name: 'Pepperoni', price: 399 }
        }
    }
    

The initial pass of Angular's Change Detection is also included in this ngOnInit phase, so any @Input() properties are available there but are purposefully undefined in the constructor.

The fact that the constructor is invoked by the JavaScript engine while ngOnInit() is called by Angular is the first and primary difference between the two methods.

When to use ngOnInit & the constructor in Angular

The constructor is used for dependency injection and initializing class members in object-oriented programming.

Implementing constructors in Angular

In Angular, dependencies are introduced into the component class using the constructor. And make the constructor as clear as you can. If the constructor logic is straightforward, unit testing can be quite simple.

Use of the ngOnInit() method in Angular

As mentioned, Angular calls ngOnInit after building the component DOM. Additionally, we will inject all necessary dependencies and processed input bindings using constructors.

Now that everything is set up, we can add the actual logic to the ngOnInit() method.

Even if the logic doesn't need DI, DOM, or input bindings, it's usual practice to utilize ngOnInit to perform actual work.

Constructor vs. ngOnInit in Angular

ngOnInit Constructor
One Angular life cycle hook technique Angular has nothing to do with the typescript
The additional Typescript feature to the class's prototype has nothing to do with Angular ngOnInit. Constructor is changed to a function that has the same name as the newly generated class.
Called by Angular By Javascript Engine
When a component is initialized, Angular calls this method. When creating a class object, the Constructor is automatically invoked.
This is actual business logic in practice Deployed to inject dependencies
When the call is made, everything is arranged Not every aspect of a component is initialized at the time it is invoked.

Despite their subtlety, the variations are significant. You are now prepared to select the appropriate OnInit action as we have covered the constructor role in detail. Our use of OnInit ensures that bindings are accessible and usable to the fullest extent.



Thanks for reading! In this blog we attempted to explain the “ difference between Constructor and ngOnInit in Angular”, and we hope that everyone will be able to understand what we were trying to say. Feel free to contact us if you need help using Angular or have any problems.

Does your Project Demand Expert Assistance?

Contact us and let our experts guide you and fulfil your aspirations for making the project successful

contactUs_img