Accessing A Child Component’s Methods From A Parent Component

In some very rare cases, you may need to call a child component’s method directly from a parent component. Generally speaking, this should be seen as only a last resort. Component communication in most cases should be limited to data binding (Both input and output), and and in some cases using a service to emit values between two components.

However, there has been times where I’ve had race conditions between two components that can only be solved by a very precise order of methods being called. This means that I need them to happen synchronously. For that, this method is a life saver , and it’s simple too!

Consider I have the following component :

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss']
})
export class ParentComponent implements OnInit {
}

And I also have a child component like so :

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit {
    callMe(value : string) { 
        console.log('Called : ' + value);
    }
}

Inside the view of parent.component.html, I place the child component.

<app-child></app-child>

Now inside my parent component, I can actually use ViewChild like so to get a direct reference to the child.

export class ParentComponent implements OnInit {
    @ViewChild(ChildComponent, {static : true}) child : ChildComponent;
}

Notice that I don’t pass in a “string” to find like we sometimes do with a ViewChild, we pass in the actual type of component we are looking for.

Then, it’s as easy as calling something on our child.

export class ParentComponent implements OnInit {
    @ViewChild(ChildComponent, {static : true}) child : ChildComponent;
	
    callMyChild(){
        child.callMe('Calling from the parent!');
    }
}

The usual ViewChild rules apply however that generally speaking, you only have access to ViewChild references after the view is initialized (So you cannot access them in an ngOnInit method, you have to use ngAfterViewInit).

Again, it’s typically much better to use data binding or a “joining service” for the two components to communicate. But often it can be hard to sync up the precise order of actions that need to happen. So for that, ViewChild is the winner.

Leave a Reply

Your email address will not be published. Required fields are marked *