Search code examples
angulartypescriptangular-components

Call child component method from parent class - Angular


I have created a child component which has a method I want to invoke.

When I invoke this method it only fires the console.log() line, it will not set the test property??

Below is the quick start Angular app with my changes.

Parent

import { Component } from '@angular/core';
import { NotifyComponent }  from './notify.component';

@Component({
    selector: 'my-app',
    template:
    `
    <button (click)="submit()">Call Child Component Method</button>
    `
})
export class AppComponent {
    private notify: NotifyComponent;

    constructor() { 
      this.notify = new NotifyComponent();
    }

    submit(): void {
        // execute child component method
        notify.callMethod();
    }
}

Child

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

@Component({
    selector: 'notify',
    template: '<h3>Notify {{test}}</h3>'
})
export class NotifyComponent implements OnInit {
   test:string; 
   constructor() { }

    ngOnInit() { }

    callMethod(): void {
        console.log('successfully executed.');
        this.test = 'Me';
    }
}

How can I set the test property as well?


Solution

  • You can do this by using @ViewChild for more info check this link

    With type selector

    child component

    @Component({
      selector: 'child-cmp',
      template: '<p>child</p>'
    })
    class ChildCmp {
      doSomething() {}
    }
    

    parent component

    @Component({
      selector: 'some-cmp',
      template: '<child-cmp></child-cmp>',
      directives: [ChildCmp]
    })
    class SomeCmp {
    
      @ViewChild(ChildCmp) child:ChildCmp;
    
      ngAfterViewInit() {
        // child is set
        this.child.doSomething();
      }
    }
    

    With string selector

    child component

    @Component({
      selector: 'child-cmp',
      template: '<p>child</p>'
    })
    class ChildCmp {
      doSomething() {}
    }
    

    parent component

    @Component({
      selector: 'some-cmp',
      template: '<child-cmp #child></child-cmp>',
      directives: [ChildCmp]
    })
    class SomeCmp {
    
      @ViewChild('child') child:ChildCmp;
    
      ngAfterViewInit() {
        // child is set
        this.child.doSomething();
      }
    }