73

It's possible to send data from the parent to a child through @Input, or to call a method on the parent from the child with @Output, but I'd like to do exactly the other way around, which is calling a method on the child from the parent. Basically something like that:

@Component({
  selector: 'parent',
  directives: [Child],
  template: `
<child
  [fn]="parentFn"
></child>
`
})
class Parent {
  constructor() {
    this.parentFn()
  }
  parentFn() {
    console.log('Parent triggering')
  }
}

and the child:

@Component({
  selector: 'child',
  template: `...`
})
class Child {
  @Input()
  fn() {
    console.log('triggered from the parent')
  }

  constructor() {}
}

Background is a kind of "get" request, i.e. for getting an up-to-date status from the child.

Now I know I could achieve that with a service and Subject/Observable, but I was wondering whether there is not something more straightforward?

mpro
  • 14,302
  • 5
  • 28
  • 43
Christophe Vidal
  • 1,894
  • 1
  • 19
  • 13
  • Does this answer your question? [Call child component method from parent class - Angular](https://stackoverflow.com/questions/38974896/call-child-component-method-from-parent-class-angular) – Liam May 12 '20 at 10:10

2 Answers2

63

I think these might be what you're looking for:

https://angular.io/guide/component-interaction#parent-interacts-with-child-via-local-variable

https://angular.io/guide/component-interaction#parent-calls-an-viewchild

You can access child properties and methods using local variables within the template or using the @ViewChild decorator in the parent's component class.

Boris Yakubchik
  • 3,861
  • 3
  • 34
  • 41
awiseman
  • 5,539
  • 1
  • 18
  • 15
  • 1
    Does the ViewChild decorator also work when my parent (table) has many children (rows) as component? I have only one instance of the child right? – Pascal May 09 '17 at 19:19
  • 4
    @Pascal For cases with multiple instances of a child component, you should use the ViewChildren decorator. https://angular.io/docs/ts/latest/api/core/index/ViewChildren-decorator.html – awiseman May 10 '17 at 14:35
61

@ViewChild is the right solution, but the documentation linked above was a bit unclear for me, so I pass a bit more friendly explanation which helped me to understand it.

Let's have a ChildComponent with a method:

whoAmI() {
  return 'I am a child!!';
}

And the parent component, where we can call method above by using '@ViewChild` technique:

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

import { ChildComponent } from './child.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {

  @ViewChild(ChildComponent) child: ChildComponent;

  ngOnInit() {
    console.log(this.child.whoAmI()); // I am a child!
  }
}
mpro
  • 14,302
  • 5
  • 28
  • 43
  • 3
    How about if there are more than one instance of same component class? As far as I have tried and seen, this triggers first instance of the class? – hasany Mar 19 '21 at 19:53
  • 1
    There's a comment answering that above, but for the sake of completeness here too... `@ViewChildren` is a thing. – Rich Jul 13 '21 at 17:28
  • 1
    Also, one small correction to this answer — you'll need to use `ngAfterViewInit` rather than `ngOnInit`. – Rich Jul 13 '21 at 19:40