Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a function as a parameter to (click) event through Angular component

I'm trying to create a component with a cancel and send buttons to avoid c&p on each form but I can't find a way to pass functions as a parameter to the component selector

HTML:

<btn-submit [cancelFunction]='test' [acceptFunction]='test'></btn-submit>

TS Parent:

test = () => console.log("this is a test");

TS Child:

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

@Component({
  selector: 'btn-submit',
  styleUrls: ['./btn.component.scss'],
  template: `
          <button class="btn" click="cancelFunction()">
              <fa name="times"></fa>
          </button>
          <button class="btn" click="acceptFunction()">
              <fa name="check"></fa>
          </button>
  `
})

export class BtnSubmitComponent {
  @Input() cancelFunction: any;
  @Input() acceptFunction: any;
}
like image 608
prevox Avatar asked Jul 26 '18 19:07

prevox


People also ask

How does Angular handle click event?

Events are handled in Angular using the following special syntax. Bind the target event name within parentheses on the left of an equal sign, and event handler method or statement on the right. Above, (click) binds the button click event and onShow() statement calls the onShow() method of a component.

How do you pass input to a component?

Firstly, we have to create a custom property to pass the data into a component. This can be done via input binding, which passes data from one component to another, generally from parent to child. This custom input binding is created by using the @Input() decorator.

What is @input annotation in Angular?

Use the @Input() decorator in a child component or directive to let Angular know that a property in that component can receive its value from its parent component. It helps to remember that the data flow is from the perspective of the child component.


2 Answers

If you want to actually pass a function in from a parent component to a child component you can do it as shown in the code below.

But using the more common @Output and EventEmitter approach as shown in other answers may be a better option. The @Output technique does not let you pass in a function, but does allow your parent component to receive events from the child component that you can respond to by calling a function in the parent component.

Here is code that allows you to pass a function in from a parent component to a child component.

Parent component

test = () => console.log("this is a test");

Parent template

<pm-star [rating]='product.starRating'
    [testFunction]='test'
    (ratingClicked)='onRatingClicked($event)'>
</pm-star>

Notice the square brackets (property binding) and it does not call a function but rather binds to a property of the component containing the function.

Child component

  @Input() testFunction: any;

Child template

<div class="crop"
     [style.width.px]="starWidth"
     [title]="rating"
     (click)="testFunction()">

I have a stackblitz with a simple working example here: https://stackblitz.com/edit/angular-jwguwk?file=src%2Fapp%2Fapp.component.ts

like image 94
DeborahK Avatar answered Oct 16 '22 14:10

DeborahK


You can use the @Output decorator in conjunction with EventEmitter class to achieve this

Child component (Typescript and markup)

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

        @Component({
          selector: 'btn-submit',
          styleUrls: ['./btn.component.scss'],
          template: `
                  <button class="btn" click="cancelFunction()">
                      <fa name="times"></fa>
                  </button>
                  <button class="btn" click="acceptFunction()">
                      <fa name="check"></fa>
                  </button>
          `
        })

        export class BtnSubmitComponent {
          @Output() clicked: EventEmitter<any> = new EventEmitter();
          cancelFunction(){
            this.clicked.emit("CANCELLED"); // Pass any payload as argument
          }
          acceptFunction{
            this.clicked.emit("ACCEPTED"); // Pass any payload as argument
          }
        }

Parent markup

<btn-submit (clicked)="onAddClicked($event)" [acceptFunction]='test'></btn-submit>

Parent Typescript function

onAddClicked(event: any){
console.log(event); // Your payload is in 'event'
}
like image 27
James Poulose Avatar answered Oct 16 '22 14:10

James Poulose