Difference between Constructor and ngOnInit
Asked Answered
Y

27

1489

Angular provides life cycle hook ngOnInit by default.

Why should ngOnInit be used, if we already have a constructor?

Yance answered 3/3, 2016 at 5:14 Comment(0)
K
1515

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:

Important to note that @Input values are not accessible in the constructor (Thanks to @tim for suggestion in comments)

Kissel answered 3/3, 2016 at 5:20 Comment(15)
Exactly, most (or even all) class based languages have contructors to ensure proper initialization order especially of classes that extend other classes where some quite difficult issues can come up, like final fields (don't know if TS has them) and similar. Contstructors are not related to Angular2, they are a TypeScript feature. Lifecycle hooks are called by Angular after some initialization took place or when some event happend to allow the component act on certain situations and to give it the chance to do some tasks at proper times.Unnumbered
Is there a limitation of actions that can be done on constructors ?Hollie
@PardeepJain What do you mean with class members?Anile
There is a block quote in angular.io/docs/ts/latest/guide/server-communication.html that also explains this: "Components are easier to test and debug when their constructors are simple, and all real work (especially calling a remote server) is handled in a separate method." - In this case that method is the ngOnInit()Genesis
As with all "best practices", I think it would be a good idea to also explain why you shouldn't be doing "work" in the constructor. This article by the Angular team lead is dense but may help: misko.hevery.com/code-reviewers-guide/… Also, less importance should be placed on the incantations required to implement OnInit (this is easy to find) and more on the critical fact that data-bindings aren't available in the constructor.Mcghee
It's not required to implement OnInit for the class, all that provides you in the TypeScript enforcement that a function called ngOnInit exists. Same applys for all life cycle hooks. I'd still explicitly define it for readability & understanding of what the component is doing at a glance. angular.io/guide/…Uphemia
If strict mode is true in tsconfig.json file like "strict": true, then you have to initialize the class members in the constructor, not in ngOnit like FormGroup.Giese
why would implementing it be best practice? it seems like it makes sense to be best practice, when you access stuff which is not available at object construction, such as Inputs; because in the ngOnInit method it will be available. otherwise it should be pretty fine to just have a constructor. This answer should imho not be the top answer...Interpleader
@Interpleader probably community also feels the same, that's could be the reason this answer is having so much upvotes and accepted too. Your thoughts are absolutely fine. It's your choice to implements it or not :)Kissel
well, maybe the community should do reasoning instead of feeling (and believing without any reason);Interpleader
It seems that by promoting 'strict' mode, which includes strictPropertyInitialization: true, Angular strongly encourages usage of constructor for initialization, even if this involves calling services etc.?Minna
Important to note that @Input values are not accessible in the constructor.Mutate
I think the main difference is data binding, so you need to initialize class members in the constructor, you can also initialize and use DI services in the constructor, the only thing you should be doing in ngOnInit imho is accessing data-binded members with @Input (since they are not available earlier). So if your component does not have @Input members you should not even need ngOnInit at allLubow
There is a circular dependency in your sources. For more information refer here - for more details see alsoGymnastics
I like the answer boy and I also I like the trick to move user from you one answer to other answer with the ink at bottom of answer. It's a infinite loop b/w your two same answers LOLSeductress
P
278

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
       ChildComponentView
         - 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:

Paddock answered 1/8, 2017 at 6:13 Comment(9)
this should be the accepted answer. it actually explains the WHY rather than repeating mantras and stating the constructor should only be used to inject dependencies.Cockup
@yannick1976, thanks! Check out the referenced articlesPaddock
@flobacca, can you please rephrase the question, it's hard to understand what you're askingPaddock
Please correct me if i’m wrong. I understood component tree is first constructed and then change the detection process. You wrote first AppComponent constructor is called (along with resolved dependencies) then ChildComponent constructor is called( along with dependencies) then Input bindings for AppComponent and then OnInit is called. But my concern is if i add life cycle hooks to both components the flow is AppComponentConstructor — ->AppComponentOnInit — →ChildComponentConstructor — →ChildComponentOnInit Why AppComponentOnInit is being called before ChildComponentConstructorVoluptuous
@user2485435, I understood component tree is first constructed and then change the detection process - yes, that's correct. Why AppComponentOnInit is being called before ChildComponentConstructor - it shouldn't be that way, do you have a demo?Paddock
<app-component></app-component> The template of AppComponent will have <app-child></app-child> Then if i use angular hooks i get AppComponentInit before ChildComponentConstructorVoluptuous
@MaxKoretskyiakaWizard you were right. I have done some mistake in my application setup. it's working as described by you. angular-c7zjsx.stackblitz.ioVoluptuous
@Max Shouldn't ngOnInit run before ngOnChanges? What is the rationale of having ngOnChanges run first?Amblyoscope
@ps0604, I don't know the rationale, it's just how it's in the sourcesPaddock
E
135

OK, first of all ngOnInit is part of Angular lifecycle, while constructor is part of ES6 JavaScript class, so the major difference starts from right here!...

Look at the below chart that I created which shows the lifecycle of Angular.

ngOnInit vs constructor

In Angular2+ we use constructor to do the DI(Dependency Injection) for us, while in Angular 1 it was happening through calling to String method and checking which dependency was injected.

As you see in the above diagram, ngOnInit is happening after the constructor is ready and ngOnChnages and get fired after the component is ready for us. All initialisation can happen in this stage, a simple sample is injecting a service and initials it on init.

OK, I also share a sample code for you to look, see how we get use of ngOnInit and constructor in the code below:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';


@Component({
 selector: 'my-app',
 template: `<h1>App is running!</h1>
  <my-app-main [data]=data></<my-app-main>`,
  styles: ['h1 { font-weight: normal; }']
})
class ExampleComponent implements OnInit {
  constructor(private router: Router) {} //Dependency injection in the constructor
  
  // ngOnInit, get called after Component initialised! 
  ngOnInit() {
    console.log('Component initialised!');
  }
}
Epicene answered 5/6, 2017 at 10:4 Comment(1)
@Epicene can we add array in styles:[] which is defined in same component?Morrissette
F
109

I think the best example would be using services. Let's say that I want to grab data from my server when my component gets 'Activated'. Let's say that I also want to do some additional things to the data after I get it from the server, maybe I get an error and want to log it differently.

It is really easy with ngOnInit over a constructor, it also limits how many callback layers I need to add to my application.

For Example:

export class Users implements OnInit{

    user_list: Array<any>;

    constructor(private _userService: UserService){
    };

    ngOnInit(){
        this.getUsers();
    };

    getUsers(){
        this._userService.getUsersFromService().subscribe(users =>  this.user_list = users);
    };


}

with my constructor I could just call my _userService and populate my user_list, but maybe I want to do some extra things with it. Like make sure everything is upper_case, I am not entirely sure how my data is coming through.

So it makes it much easier to use ngOnInit.

export class Users implements OnInit{

    user_list: Array<any>;

    constructor(private _userService: UserService){
    };

    ngOnInit(){
        this.getUsers();
    };

    getUsers(){
        this._userService.getUsersFromService().subscribe(users =>  this.user_list = users);
        this.user_list.toUpperCase();
    };


}

It makes it much easier to see, and so I just call my function within my component when I initialize instead of having to dig for it somewhere else. Really it's just another tool you can use to make it easier to read and use in the future. Also I find it really bad practice to put function calls within a constructor!

Fino answered 3/3, 2016 at 5:30 Comment(7)
Your example could be simplified if you just set user_list to the Observable. Angular2 has the async pipe, so there wouldn't be any problems there.Epidiascope
@Morgan, just for me to learn a small thing here, why do you first create a function getUsers and then insert it into ngOnInit? Is it not less code to just write it in ngOnInit? I am jsut wondering why people do it this way? Is it so that you can re-use the code if you wanted too? Thanks.Trickish
@AlfaBravo I would guess that the reason is to give the two lines inside getUsers() some meaning. Plus, if a third line would get added to ngOnInit() unrelated to the existing two lines, it could be confusing to future maintainers.Goddamn
As seen in the answer below this makes no difference if it's in the constructor. This is not a real answer to the purpose.Nth
I don't see how this answers the question at all. Why couldn't you just put the code in the constructor ?Gonion
@AlfaBravo also, it could happen that you want to call getUsers() again later.Jarrettjarrid
@Morgan why can't you just do constructor(private _userService: UserService){ this.getUsers(); }; Kazantzakis
P
84

I will just add one important thing that was skipped in the explanations above and explains when you MUST use ngOnInit.

If you are doing any manipulation of the component's DOM via e.g. ViewChildren, ContentChildren or ElementRef, your native elements will not be available during the constructor phase.

However, since ngOnInit happens once the component has been created and the checks (ngOnChanges) have been called you can access the DOM at this point.

export class App implements OnInit, AfterViewInit, AfterContentInit {
  @Input() myInput: string;
  @ViewChild() myTemplate: TemplateRef<any>;
  @ContentChild(ChildComponent) myComponent: ChildComponent; 

  constructor(private elementRef: ElementRef) {
     // this.elementRef.nativeElement is undefined here
     // this.myInput is undefined here
     // this.myTemplate is undefined here
     // this.myComponent is undefine here
  }

  ngOnInit() {
     // this.elementRef.nativeElement can be used from here on
     // value of this.myInput is passed from parent scope
     // this.myTemplate and this.myComponent are still undefined
  }
  ngAfterContentInit() {
     // this.myComponent now gets projected in and can be accessed
     // this.myTemplate is still undefined
  }

  ngAfterViewInit() {
     // this.myTemplate can be used now as well
  }
}
Peake answered 29/1, 2018 at 11:16 Comment(6)
Nope. For @ViewChildren in particular, you need to use the ngAfterViewInit method. See here: #46315234Oversight
Thanks, @Oversight for pointing it out. I have now improved the answerPeake
This is the most beautiful response. The reason we study Angular Life Cycle hooks mostly boils down to these use-cases.Buchheim
Glad you found it helpful, @N.RajPeake
Has the API for elementRef changed? I've tested and this.elementRef.nativeElement is not undefined in constructor.Draconian
Most likely. This answer was posted 4-5 years ago. Before the entire Ivy refactoringPeake
K
71

The first one (constructor) is related to the class instantiation and has nothing to do with Angular2. I mean a constructor can be used on any class. You can put in it some initialization processing for the newly created instance.

The second one corresponds to a lifecycle hook of Angular2 components:

Quoted from official angular's website:

  • ngOnChanges is called when an input or output binding value changes
  • ngOnInit is called after the first ngOnChanges

So you should use ngOnInit if initialization processing relies on bindings of the component (for example component parameters defined with @Input), otherwise the constructor would be enough...

Kukri answered 3/3, 2016 at 6:36 Comment(0)
S
47

Short and simple answer would be,

Constructor : constructor is a default method runs (by default) when component is being constructed. When you create an instance of a class that time also constructor(default method) would be called. So in other words, when the component is being constructed or/and an instance is created constructor(default method) is called and relevant code is written within is called. Basically and generally in Angular2, it used to inject things like services when the component is being constructed for further use.

OnInit: ngOnInit is component's life cycle hook which runs first after constructor(default method) when the component is being initialized.

So, Your constructor will be called first and Oninit will be called later after constructor method.

boot.ts

import {Cmomponent, OnInit} from 'angular2/core';
import {ExternalService} from '../externalService';

export class app implements OnInit{
   constructor(myService:ExternalService)
   {
           this.myService=myService;
   }

   ngOnInit(){
     // this.myService.someMethod() 
   }
}

Resources: LifeCycle hook

You can check this small demo which shows an implementation of both things.

Solo answered 3/3, 2016 at 5:20 Comment(5)
I think "constructor is something which runs or called when component is initialized." is misleading. The constructor is a feature of the class not of the component. I'd say the instance of the class only becomes a component after the constructor was called and Angular did it's initialization.Unnumbered
Yes changed the statement you can check now.Solo
Hmm, IMHO it's still the same "constructor(default method) is something which runs or called when component is constructed.". It's not only called when a component is constructed but also for services or when code like new MyClass() is executed. I think it's misleading to say constructors are about components, they are about classes and initializing instances of these classes. A component just happens to be such a class. Otherwise I think it's a good answer.Unnumbered
Yes absolutely. Forgot to mention that when you create an object of a class also that time constructor would be called. But this answer has been written in angular2 context. To know the best answer you must be knowing OOPs basics. Still I'll update answer.Solo
@GünterZöchbauer, I don't think that it's a correct assertion that is a feature of the class not of the component. From the programming language perspective yes, this is correct. But I can successfully work with components without any lifecycle hooks at all. But I can't work with a component without a constructor if I need DI because that's the only injectable place. See my answerPaddock
I
36

The main difference between constructor and ngOnInit is that ngOnInit is lifecycle hook and runs after constructor. Component interpolated template and input initial values aren't available in constructor, but they are available in ngOnInit.

The practical difference is how ngOnInit affects how the code is structured. Most initialization code can be moved to ngOnInit - as long as this doesn't create race conditions.

Constructor antipattern

A substantial amount of initialization code makes constructor method hard to extend, read and test.

A usual recipe for separating initialization logic from class constructor is to move it to another method like init:

class Some {
  constructor() {
    this.init();
  }

  init() {...}
}

ngOnInit can serve this purpose in components and directives:

constructor(
  public foo: Foo,
  /* verbose list of dependencies */
) {
  // time-sensitive initialization code
  this.bar = foo.getBar();
}

ngOnInit() {
  // rest of initialization code
}

Dependency injection

The primary role of class constructors in Angular is dependency injection. Constructors are also used for DI annotation in TypeScript. Almost all dependencies are assigned as properties to class instance.

Average component/directive constructor is already big enough because it can have multiline signature due to dependencies, putting unnecessary intialization logic to constructor body contributes to the antipattern.

Asynchronous initialization

Asynchronous initialization constructor can often be considered antipattern and have smell because class instantiation finishes before asynchronous routine does, and this can create race conditions. If it's not the case, ngOnInit and other lifecycle hooks are better places for this, particularly because they can benefit from async syntax:

constructor(
  public foo: Foo,
  public errorHandler: ErrorHandler
) {}

async ngOnInit() {
  try {
    await this.foo.getBar();
    await this.foo.getBazThatDependsOnBar();
  } catch (err) {
    this.errorHandler.handleError(err);
  }
}

If there are race conditions (including the one that a component shouldn't appear on initialization error), asynchronous initialization routine should take place before component instantiation and be moved to parent component, router guard, etc.

Unit testing

ngOnInit is more flexible than a constructor and provides some benefits for unit testing that are explained in detail in this answer.

Considering that ngOnInit isn't called automatically on component compilation in unit tests, methods that are called in ngOnInit can be spied or mocked after component instantiation.

In exceptional cases ngOnInit can be entirely stubbed to provide isolation for other component units (for instance, some template logic).

Inheritance

Child classes can only augment constructors, not replace them.

Since this cannot be referred before super(), this puts restrictions on initialization precedence.

Considering that Angular component or directive uses ngOnInit for time-insensitive initialization logic, child classes can chose whether super.ngOnInit() is called and when:

ngOnInit() {
  this.someMethod();
  super.ngOnInit();
}

This would be impossible to implement with constructor alone.

Inaugural answered 9/2, 2018 at 12:35 Comment(0)
N
28

Like a lot of other languages, you can initialize variables at the class level, the constructor, or a method. It is up to the developer to decide what is best in their particular case. But below are a list of best practices when it comes to deciding.

Class level variables

Usually, you will declare all your variables here that will be used in the rest of you component. You can initialize them if the value doesn't depend on anything else, or use const keyword to create constants if they will not change.

export class TestClass{
    let varA: string = "hello";
}

Constructor

Normally it's best practice to not do anything in the constructor and just use it for classes that will be injected. Most of the time your constructor should look like this:

   constructor(private http: Http, private customService: CustomService) {}

this will automatically create the class level variables, so you will have access to customService.myMethod() without having to do it manually.

NgOnInit

NgOnit is a lifecycle hook provided by the Angular 2 framework. Your component must implement OnInit in order to use it. This lifecycle hook gets called after the constructor is called and all the variables are initialized. The bulk of your initialization should go here. You will have the certainty that Angular has initialized your component correctly and you can start doing any logic you need in OnInit versus doing things when your component hasn't finished loading properly.

Here is an image detailing the order of what gets called:

enter image description here

https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html

TLDR

If you are using Angular 2 framework and need to interact with certain lifecycle events, use the methods provided by the framework for this to avoid problems.

Neutretto answered 6/3, 2017 at 21:59 Comment(0)
J
22

To test this, I wrote this code, borrowing from the NativeScript Tutorial:

user.ts

export class User {
    email: string;
    password: string;
    lastLogin: Date;

    constructor(msg:string) {        
        this.email = "";
        this.password = "";
        this.lastLogin = new Date();
        console.log("*** User class constructor " + msg + " ***");
    }

    Login() {
    }
}

login.component.ts

import {Component} from "@angular/core";
import {User} from "./../../shared/user/user"

@Component({
  selector: "login-component",
  templateUrl: "pages/login/login.html",
  styleUrls: ["pages/login/login-common.css", "pages/login/login.css"]
})
export class LoginComponent {

  user: User = new User("property");  // ONE
  isLoggingIn:boolean;

  constructor() {    
    this.user = new User("constructor");   // TWO
    console.log("*** Login Component Constructor ***");
  }

  ngOnInit() {
    this.user = new User("ngOnInit");   // THREE
    this.user.Login();
    this.isLoggingIn = true;
    console.log("*** Login Component ngOnInit ***");
  }

  submit() {
    alert("You’re using: " + this.user.email + " " + this.user.lastLogin);
  }

  toggleDisplay() {
    this.isLoggingIn = !this.isLoggingIn;
  }

}

Console output

JS: *** User class constructor property ***  
JS: *** User class constructor constructor ***  
JS: *** Login Component Constructor ***  
JS: *** User class constructor ngOnInit ***  
JS: *** Login Component ngOnInit ***  
Jeromejeromy answered 24/5, 2016 at 14:58 Comment(0)
S
18

The above answers don't really answer this aspect of the original question: What is a lifecycle hook? It took me a while to understand what that means until I thought of it this way.

1) Say your component is a human. Humans have lives that include many stages of living, and then we expire.

2) Our human component could have the following lifecycle script: Born, Baby, Grade School, Young Adult, Mid-age Adult, Senior Adult, Dead, Disposed of.

3) Say you want to have a function to create children. To keep this from getting complicated, and rather humorous, you want your function to only be called during the Young Adult stage of the human component life. So you develop a component that is only active when the parent component is in the Young Adult stage. Hooks help you do that by signaling that stage of life and letting your component act on it.

Fun stuff. If you let your imagination go to actually coding something like this it gets complicated, and funny.

Socalled answered 9/12, 2016 at 19:52 Comment(0)
L
9

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.

Lahey answered 2/5, 2017 at 6:14 Comment(0)
D
9

constructor() is the default method in the Component life cycle and is used for dependency injection. Constructor is a Typescript Feature.

ngOnInit() is called after the constructor and ngOnInit is called after the first ngOnChanges.

i.e.:

Constructor() --> ngOnChanges() --> ngOnInit()

as mentioned above ngOnChanges() is called when an input or output binding value changes.

Dimmer answered 8/6, 2018 at 9:45 Comment(0)
L
8

Two things to observe here:

  1. Constructor is called whenever an object is created of that class.
  2. ngOnInit called once the component is created.

Both have different usability.

Lippold answered 12/6, 2017 at 12:34 Comment(0)
M
7

Constructor: The constructor method on an ES6 class (or TypeScript in this case) is a feature of a class itself, rather than an Angular feature. It’s out of Angular’s control when the constructor is invoked, which means that it’s not a suitable hook to let you know when Angular has finished initialising the component. JavaScript engine calls the constructor, not Angular directly. Which is why the ngOnInit (and $onInit in AngularJS) lifecycle hook was created. Bearing this in mind, there is a suitable scenario for using the constructor. This is when we want to utilise dependency injection - essentially for “wiring up” dependencies into the component.

As the constructor is initialised by the JavaScript engine, and TypeScript allows us to tell Angular what dependencies we require to be mapped against a specific property.

ngOnInit is purely there to give us a signal that Angular has finished initialising the component.

This phase includes the first pass at Change Detection against the properties that we may bind to the component itself - such as using an @Input() decorator.

Due to this, the @Input() properties are available inside ngOnInit, however are undefined inside the constructor, by design

Mcgannon answered 20/12, 2017 at 6:47 Comment(1)
Right on the mark .... perfect and covered most points for this question "constructor vs ngOnInit"Varistor
R
5

Constructor is the first to execute, and it happens sometimes when @input data is null! so we use Constructor to inject services and ngOnInit happens after. Example for constructor:

 constructor(translate: TranslateService, private oauthService: OAuthService) {
    translate.setDefaultLang('En');
        translate.use('En');}

Example for ngOnInit:

ngOnInit() {
    this.items = [
      { label: 'A', icon: 'fa fa-home', routerLink: ['/'] },
      { label: 'B', icon: 'fa fa-home', routerLink: ['/'] }]
}

I think that ngOnInit is like InitialComponents() in winForm .

Reproduction answered 5/12, 2018 at 6:34 Comment(0)
B
4

Both methods have different goals/responsibilities. The task of the constructor (which is a language supported feature) is to make sure that the representation invariant holds. Otherwise stated to make sure that the instance is valid by giving correct values to the members. It is up to the developer to decide what 'correct' means.

The task of the onInit() method (which is an angular concept) is to allow method invocations on a correct object (representation invariant). Each method should in turn make sure that the representation invariant holds when the method terminates.

The constructor should be used to create 'correct' objects, the onInit method gives you the opportunity to invoke method calls at a well defined instance.

Bibber answered 9/1, 2017 at 19:20 Comment(0)
M
2

The Constructor is executed when the class is instantiated. It has nothing do with the angular. It is the feature of Javascript and Angular does not have the control over it

The ngOnInit is Angular specific and is called when the Angular has initialized the component with all its input properties

The @Input properties are available under the ngOnInit lifecycle hook. This will help you to do some initialization stuff like getting data from the back-end server etc to display in the view

@Input properties are shows up as undefined inside the constructor

Manservant answered 18/11, 2019 at 11:39 Comment(0)
M
1

constructor() is used to do dependency injection.

ngOnInit(), ngOnChanges() and ngOnDestroy() etc. are lifecycle methods. ngOnChanges() will be the first to be called, before ngOnInit(), when the value of a bound property changes, it will NOT be called if there is no change. ngOnDestroy() is called when the component is removed. To use it, OnDestroy needs to be implemented by the class.

Mansour answered 9/8, 2017 at 12:29 Comment(1)
agree, this is short and clear. For example, constructor() is for adding service objects, ngOnInit() is for manipulating components with necessary service function calls.Grisby
R
1

In the Angular life-cycles

1) Angular injector detect constructor parameter('s) and instantiate class.

2) Next angular call life-cycle

Angular Lifecycle Hooks

ngOnChanges --> Call in directive parameters binding.

ngOnInit --> Start angular rendering...

Call other method with state of angular life-cycle.

Rameriz answered 4/11, 2017 at 6:2 Comment(0)
L
1

The constructor is called when Angular "instanciates/constructs" the component. The ngOnInit method is a hook which represents the initialization part of the component lifecycle. A good practice is to use it only for service injection:

constructor(private 
    service1: Service1,
    service2: Service2
){};

Even if it is possible, you should not do some "work" inside. If you want to launch some action which have to occur at component "initialization", use ngOnInit:

ngOnInit(){
    service1.someWork();
};

Moreover, actions that involve input properties, coming from a parent component, can't be done in the contructor. They should be placed in ngOnInit method or another hook. It is the same for element related to the view (the DOM), for example, viewchild elements:

@Input itemFromParent: string;
@ViewChild('childView') childView;

constructor(){
    console.log(itemFromParent); // KO
    // childView is undefined here
};

ngOnInit(){
    console.log(itemFromParent); // OK
    // childView is undefined here, you can manipulate here
};
Lester answered 18/1, 2019 at 12:23 Comment(0)
K
1

Constructor is a function executed when component (or other class) is built.

ngOnInit is a function belonging to a component life-cycle method groups and they are executed in a diffrent moment of our component (that's why name life-cycle). Here is a list of all of them:

enter image description here Constructor will be executed before any life-cycle function.

Kotta answered 28/5, 2019 at 15:30 Comment(0)
L
1

Constructor

The constructor function comes with every class, constructors are not specific to Angular but are concepts derived from Object oriented designs. The constructor creates an instance of the component class.

OnInit

The ngOnInit function is one of an Angular component’s life-cycle methods. Life cycle methods (or hooks) in Angular components allow you to run a piece of code at different stages of the life of a component. Unlike the constructor method, ngOnInit method comes from an Angular interface (OnInit) that the component needs to implement in order to use this method. The ngOnInit method is called shortly after the component is created.

Landmark answered 28/10, 2019 at 12:18 Comment(0)
C
1

Constructor is part of ES6 also typescript is using es6 syntax and now days es7 as well so you can utilise advance feature which typescript would compile to es5/es4 (as per you define) to provide support to old browser.

While ngOnInIt is lifecycle hook of angular. It is initialised when your component is initialised. (Consider it's state as born of any new life)

It's wise to use ngOnInIt compare to constructor, because you have another lifecycle hook like ngOnDestory (Consider it as death of any life). Here you can unsubscribe to any observable which is good to prevent any memory leak.

Incase any question feel free to comment on this answer.

Courtund answered 1/9, 2020 at 10:1 Comment(0)
C
1

constructor() can accept parameter and can used for dependency injection or constructor() is for adding service objects.

constructor is called before ngOnint();

ngOnInit() is for manipulating components with necessary service function calls or Generally, calls of services in the ngOnInit () and not in the constructor

Cabral answered 22/3, 2021 at 11:35 Comment(0)
B
0

I found the answer and I tried to translate it to english: This question still arised, even in technical interviews. In fact, there is a big resemblance between the two, but also there are some differences.

  • The constructor is part of ECMAScript. On the other hand ngOnInit() is a notion of angular.

  • We can call the constructors in all classes even if we do not use Angular

  • LifeCycle: The constructor is called before ngOnInt ()

  • In the constructor we can not call HTML elements. However, in ngOnInit () we can.

  • Generally, calls of services in the ngOnInit () and not in the constructor

    Source: http://www.angular-tuto.com/Angular/Component#Diff

Baklava answered 13/3, 2019 at 8:33 Comment(0)
S
0

Constructor is the default method provided by Typescript class, which dedicated to initializes the class members generally is used for dependencies injections services like the example code above, or timer initialization, socket connection initialization

export class AppComponent {
  title = 'angular-fork-join';
  constructor(private http: HttpClient) {}

ngOnInit: is a lifecycle hook called when the component is initialized provided by Angular which dedicated for example for business logic, data initialization, API calls, etc .., example code that demonstrates API call :

export class HomeComponent implements OnInit {

  products = [];

  constructor(private dataService: DataService) { }

  ngOnInit() {

    this.dataService.sendGetRequest().subscribe((data: any[])=>{
      console.log(data);
      this.products = data;
    })  
  }

} 
Sciamachy answered 13/7, 2021 at 19:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.