Search code examples
angularmouseevent

How to pass $event from a programmatically created function that takes $event arg on from expected mouseclick?


I have a click handler on an angular HTML template that passes the $event argument to the handler function. I need to call this function on ngOnInit programmatically to essentially bootstrap my component with default data as if the user had clicked the button:

Here is the template reference:

<button *ngIf="options?.addRow"
  mat-button
  (click)="addRow($event)">
  <span>Add Row</span>
</button>

Here is the addRow method:

addRow(event: any) {
    const currentData = cloneDeep(this.formArrayValues);
    currentData.push(this.emptyRowFromColumnDef); // Append new row to END of table
    this.updateTableData(currentData);
    if (this.paginationEnable && this.paginator) {
      timer().subscribe(() => this.paginator.lastPage());
    }
    timer(1).subscribe(() => this.changeDetectorRef.markForCheck());
    event.preventDefault(); // EVENT arg is needed here
  }

And here is where I need to programmatically call addRow in ngOnInit() but I need to pass the event as if it were a manual click:

 ngOnInit() {
   event: ? // how to define the $event to pass to addRow?
   this.addRow(this.event);
 }

Solution

  • I don't think it makes sense to create a fake event just to pass into your method. You could make the event optional:

    addRow(event?: MouseEvent) {
        const currentData = cloneDeep(this.formArrayValues);
        currentData.push(this.emptyRowFromColumnDef); // Append new row to END of table
        this.updateTableData(currentData);
        if (this.paginationEnable && this.paginator) {
          timer().subscribe(() => this.paginator.lastPage());
        }
        timer(1).subscribe(() => this.changeDetectorRef.markForCheck());
        event?.preventDefault();
    }
    

    Then just call it without the event (since you don't really need to 'preventDefault' when there's not actually an event).

     ngOnInit() {
       this.addRow();
     }
    

    Another way to go could be to create two separate methods, once for your template to call, and one that does the addRow logic:

    addRow() {
        const currentData = cloneDeep(this.formArrayValues);
        currentData.push(this.emptyRowFromColumnDef); // Append new row to END of table
        this.updateTableData(currentData);
        if (this.paginationEnable && this.paginator) {
          timer().subscribe(() => this.paginator.lastPage());
        }
        timer(1).subscribe(() => this.changeDetectorRef.markForCheck());
    }
    
    onClick(event: MouseEvent) {
       this.addRow();
       event.preventDefault();
    }
    

    Then your ngOnInit can simply call addRow().


    I must ask though, why do you need to preventDefault on a button anyway?

    If it's inside a form and you don't want it to submit the form, you can set the type to 'button': <button type="button">.