ngOnInit not fired when inheritance is involved (on Android)


#1

Hello, it’s to report a little problem I encountered on Ionic 2.

Take the simple inheritance below, where ngOnInit is used.

Parent :

import { Component, Input, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { FormValidationsService } from '../../providers/formvalidations.service';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';

@Component({
  selector: 'control-messages',
  template: `<p class="error-message" *ngIf="errorMessage">{{errorMessage}}</p>`
})
export class ControlMessagesComponent implements OnInit {
  errorMessage: string;
  @Input() control: FormControl;

  constructor() { }

  getErrorMessage() {
    for (let propertyName in this.control.errors) {
      if (this.control.errors.hasOwnProperty(propertyName) && this.control.dirty) {
        return FormValidationsService.getValidatorErrorMessage(propertyName, this.control.errors[propertyName]);
      }
    }
    
    return null;
  }
  
  ngOnInit(){
      console.log("parent OnInit");      
      this.control.valueChanges
      .debounceTime(300)
      .distinctUntilChanged()
      .subscribe(
        (x) => { 
          this.errorMessage = this.getErrorMessage();
        },
        (err) => console.error(err)
      );
  }
}

Child :

import { Component, Input} from '@angular/core';
import { FormControl } from '@angular/forms';

import { ControlMessagesComponent } from "../control-messages/control-messages.component";
@Component({
  selector: 'control-messages-item',
  template: `<ion-item class="error-message item-text-wrap" text-wrap *ngIf="errorMessage">{{errorMessage}}</ion-item>`
})
export class ControlMessagesItemComponent extends ControlMessagesComponent{
  errorMessage: string;
  @Input() control: FormControl;
}

This code works in a browser, when you use “” in a page, when you open your console you will see “parent OnInit”.

BUT this won’t work on Android build (I din’t try on iOS).

To make it work you just have to add “ngOnInit”, and call the super.OnInit

export class ControlMessagesItemComponent extends ControlMessagesComponent{
  errorMessage: string;
  @Input() control: FormControl;

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

You don’t need to “implements OnInit”, since it’s already done in the parent.

It’s just a message to help the people who’ll encounter the same problem / to prevent the Ionic Team, but it’s a minor bug so…

Your system information:

Cordova CLI: 6.4.0
Ionic Framework Version: 2.0.0-rc.3
Ionic CLI Version: 2.1.13
Ionic App Lib Version: 2.1.7
Ionic App Scripts Version: 0.0.45
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Windows 10
Node Version: v6.9.1
Xcode version: Not installed

#2

sounds like the build process removes the onInit because it is not used explicit in your source code.

And the Problem is --> if you want to extend a class, you should call the parent constructor in the child constructor, to store all parent members on your child object. but that is not that easy for components (think about dependency injection and so on)

So to get thinks work, like you want, you have to call

super(.., ...);

in your constructor of the child component.