amansoni211
amansoni211

Reputation: 919

Call function in child component defined in parent component angular 2

I have two components app and child. in child component I have button on click of which I am calling a function (function name is assigned to a variable which make it dynamic) which is defines in app component. But this is not working. Any help?

app.ts

selector: 'my-app',
template: `
  <div>
    <h2>Hello {{name}}</h2>
    <child-comp></child-comp>
    <p>{{data}}</p>
  </div>
`,
})
export class App {
  name:string;
  data: string;
  constructor() {
    this.name = 'Angular2'
  }
  dummyFunction(){  // I want to call this function
      data = "function called";
  }
}

Child.ts

@Component({
  selector: 'child-comp',
  template: `
    <input type="button" value="click me" (click) = [funcName]()>  // Here I am calling the function which is assign to a variable
  `,
})
export class ChildComp {
  funcName: string;
  constructor() {
    funcName = 'dummyFunction';  // assigning function name to variable
  }
}

Attaching Plunker

Upvotes: 0

Views: 3986

Answers (2)

Tiep Phan
Tiep Phan

Reputation: 12596

if call only child method

Child.ts

@Component({
  selector: 'child-comp',
  template: `
    <input type="button" value="click me" (click)="this[funcName]()">  // Here I am calling the function which is assign to a variable
  `,
})
export class ChildComp {
  funcName: string;
  constructor() {
    this.funcName = 'dummyFunction';  // assigning function name to variable
  }
  dummyFunction() {
    console.log('do something')
  }
}

or

@Component({
  selector: 'child-comp',
  template: `
    <input type="button" value="click me" (click)="funcName()"> // callhere
  `,
})
export class ChildComp {
  funcName: Fn;
  constructor() {
    this.funcName = this.dummyFunction.bind(this);  // assigning function to variable
  }
  dummyFunction() {
    console.log('do something')
  }
}

if you need communicate from parent and child:

@Component({
  selector: 'child-comp',
  template: `
    <input type="button" value="click me" (click)="funcName()"> // callhere
  `,
})
export class ChildComp {
  @Input()
  funcName: Fn;
  constructor() {
  }
}

@Component({
selector: 'my-app',
template: `
  <div>
    <h2>Hello {{name}}</h2>
    <child-comp [funcName]="dummyFunction"></child-comp>
    <p>{{data}}</p>
  </div>
`,
})
export class App {
  name:string;
  data: string;
  constructor() {
    this.name = 'Angular2';
    this.dummyFunction = this.dummyFunction.bind(this);
  }
  dummyFunction(){  // I want to call this function
      data = "function called";
  }
}

or using Output

import {Component, Output, EventEmitter } from '@angular/core'

@Component({
  selector: 'child-comp',
  template: `
    <input type="button" value="click me" (click)="onClick($event)">
  `,
})
export class ChildComp {

  @Output() eventName = new EventEmitter();
  constructor() {

  }
  onClick(e) {
    // do something here
    this.eventName.emit(e);
  }
}

parent:

@Component({
selector: 'my-app',
template: `
  <div>
    <h2>Hello {{name}}</h2>
    <child-comp (eventName)="dummyFunction()"></child-comp>
    <p>{{data}}</p>
  </div>
`,
})
export class App {
  name:string;
  data: string;
  constructor() {
    this.name = 'Angular2';
  }
  dummyFunction(){  // I want to call this function
      data = "function called";
  }
}

Upvotes: 1

Garth Mason
Garth Mason

Reputation: 8001

I don't think you can do exactly what you are describing, but can achieve the same thing using the Output decorator and EventEmitter as described in the documentation for parent-child component communication.

Your child component can emit an event, buttonClicked below, and the parent component (i.e. app) can bind to that event with the required callback (i.e. dummyFunction())

App component

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <child-comp (buttonClicked)="dummyFunction()"></child-comp>
      <p>{{data}}</p>
    </div>
  `,
})
export class App {
  name:string;
  data: string;
  constructor() {
    this.name = 'Angular2'
  }

  dummyFunction(){ // I want to call this function
    this.data = "function called";
  }
}

And child component

import {Component, Output, EventEmitter} from '@angular/core'

@Component({
  selector: 'child-comp',
  template: `
    <input type="button" value="click me" (click) = "onClick($event)"> // Here I am calling the function which is assign to a variable
  `,
})
export class ChildComp {

  @Output() buttonClicked = new EventEmitter();
  constructor() {
  }

  onClick($event){
    this.buttonClicked.emit($event);
  }
}

Upvotes: 3

Related Questions