Lifecycle events inside custom components doesnt work

I have a custom component:

import { Component } from '@angular/core';

@Component({
  selector: 'net-tree',
  templateUrl: 'net-tree.html'
})
export class NetTree {

  text: string;

  constructor() {
    console.log('Hello NetTree Component');
    this.text = 'Hello World';
  }
  ionViewDidLoad() {
    console.log('Called!')
  }
}

But ionViewDidLoad() dont triggered. Is there anyway to do this?

HI @Koleman

Can you use NavController module in your Project


import { Component } from '@angular/core';
import {NavController, Platform} from 'ionic-angular';


@Component({
  selector: 'net-tree',
  templateUrl: 'net-tree.html'
})
export class NetTree {

  text: string;

  constructor(private navController: NavController, private platform: Platform) {
    this.platform.ready().then(() => {
    console.log('Hello NetTree Component');
   });
    this.text = 'Hello World';
  }
  ionViewDidLoad() {
    console.log('Called!')
  }
}

Hope this will solve your issue.

Feel free to mark it as a solution and you can always like the answer by clicking heart icon.

I forget to mention that my component lies(not a typical page) inside module that imported to main module

import { NgModule }  from '@angular/core';
import {FormsModule} from '@angular/forms';
import {CommonModule} from '@angular/common';
import {NetTree} from './net-tree/net-tree';
import {IonicPageModule} from 'ionic-angular';

@NgModule({
  declarations: [
    NetTree
  ],
  imports: [
    FormsModule,
    CommonModule,
    IonicPageModule.forChild(NetTree),
  ],
  exports: [
    NetTree
  ]
})
export class CustomComponentsModule {}

So i dont have access to navController and so on.

@Koleman The lifecycle hook ionViewDidLoad() and the likes works only on Ionic pages (the ones you call with NavController.push() and NavController.setRoot()). The angular events like ngOnInit() works though.

If you want the ionic page events, you can inject the ViewController and subscribe to its observables:

import { Component } from '@angular/core';
import { ViewController } from 'ionic-angular';

@Component({
	selector: 'net-tree',
	templateUrl: 'net-tree.html'
})
export class NetTree {

	text: string;

	constructor(private viewController: ViewController) {
		console.log('Hello NetTree Component');
		this.text = 'Hello World';

		// didLoad is basically the same as the first didEnter
		// it has a _didLoad observable but the '_' makes it seems like a private property
		this.viewController.didEnter.first().subscribe(
			() => console.log('Called!')
		);
	}
}

This will work only if you can inject the ViewController on the component though (like in a subcomponent of a page).

Update

Now that I see that you use IonicPageModule.forChild() in your component, I think it should works as an Ionic page. If the ViewController approach doesn’t work, you can try to anotate your NetTree component with @IonicPage(). I’m not using lazy loading pages yet, but there is information about how to create such a page here.

2 Likes

Just FYI, one recommended design pattern is to make your pages smart and your components dumb. The reason is to reduce the overhead created by Angular change detection. So while your pages know about their context, components only know about the inputs they receive from @Input. I’ve seen some debate about how much this really matters, and I’m not sure myself. But you might be in a situation where you solve this problem, and discover that it creates a slowdown.

Yea, i’ve also thought in this way.

I doubt it would actually harm anything, but I would remove the IonicPageModule line from that module file. That should only be for pages.