ceyon67
ceyon67

Reputation: 141

Angular 6 call and pass a function from parent to child component

I have a button in a child form component and in the from parent component I want to push a function to the child component when the onClose() function is clicked from within the child component. I've tried the method below but the issue is it will work on the first form but not the rest. I would also like to pass other functions as well, including a onSubmit. For me to proceed I will need to figure out what i'm doing wrong here. I've been at this for a few days now any help is appreciated.Thanks

child form component, in the template url it contains the button for Onclose()

import { Component, OnInit, NgModule, Input, ViewChild, Output, EventEmitter } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, Validators, AbstractControl,  ValidatorFn,Form } from '@angular/forms';
import { BsDatepickerConfig } from 'ngx-bootstrap/datepicker';

@Component({
    selector: 'app-editgraphs',
    templateUrl: './editgraphs.component.html',
    styleUrls: ['./editgraphs.component.scss']
})
export class EditgraphsComponent implements OnInit {
    @Input() eGraphtitle: string;
    @Output() close: EventEmitter<any> = new EventEmitter();
    graphDataForm: FormGroup;
    constructor(private fb: FormBuilder,){}
    ngOnInit(): void {
     this.graphDataForm = this.fb.group({
    sDepartment: new FormControl(null, [Validators.required])
      });

      }

            onClose() {this.close.emit();}
            onClose2() {this.close.emit();}


parent component

import { Component, Inject, OnInit, ViewChild, ViewChildren } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { debug } from 'util';
import { EditgraphsComponent} from './../../../shared/forms/editgraphs/editgraphs.component'

@Component({
    selector: 'app-payments',
    templateUrl: './payments.component.html',
    styleUrls: ['./payments.component.scss']


})
export class PaymentsComponent {
    @ViewChild(EditgraphsComponent) private graphComponent: EditgraphsComponent;
    //graph modal titles
    egraph1Title: string = 'YTD Comparison Data';
constructor() {}

onClose() {

    this.graphComponent.graphDataForm.reset();
    console.log('Resseting and closing YCPC graph.');
}


onClose2() {

    this.graphComponent.graphDataForm.reset();
    console.log('Resseting and closing CMCPG graph.');
}

Parent Template URL


<app-editgraphs #graphComponent  [eGraphtitle]="egraph1Title" (close)="onClose($event)"></app-editgraphs>
    <app-editgraphs #graphComponent  [eGraphtitle]="egraph2Title" (close)="onClose2($event)"></app-editgraphs>

Upvotes: 13

Views: 29260

Answers (1)

firegloves
firegloves

Reputation: 5709

Function parameter approach

You can pass a function like an @Input like this.

Parent component

export class PArentComponent {

  fn = function() {
    console.log('hello');
  };
}

Parent template

 <app-child [function]="fn"></app-child>

Child component

export class ChildComponent implements OnInit {

  @Input() function: any;

 ngOnInit() {
       this.function();
 }
}

EventEmitter Approach

If you need to execute a function that needs to access parent scope variables you could choose an event approach. Contrary to @Input you can use @Output that is the angular way to communicate events from child to parent.

You can define an event in your child component like this:

export class ChildComponent implements OnInit {

 @Output() onClose = new EventEmitter();

 ngOnInit() {
 }

 closeModal() {
   // DO SOMETHING

   // emit event onClose
   this.onClose.emit();
   // you can pass also some payload into the event
   this.onClose.emit('all closed');
 }
}

Child template

<button (click)="closeModal()"></button>

Then in your Parent Component's template you can catch child component's event like all other events in angular:

<app-child (onClose)="execOnClose($event)"></app-child>

This piece of code intercepts an onClose event with (onClose) and executes parent component's execOnClose() method.

So let's look at the parent component

export class ParentComponent {

  execOnClose($event: any) {
    // DO SOMETHING
  }
}

Upvotes: 30

Related Questions