Home > Software engineering >  How to access one button in *ngFor loop and assign it public delete method on click event
How to access one button in *ngFor loop and assign it public delete method on click event

Time:03-30

I have loop that goes over buttons and assigns properties.

.html

 <ng-container matColumnDef="actions">
          <mat-header-cell mat-header-cell *matHeaderCellDef>{{
            'scenarios.scenariosList.actionsColumn' | translate
          }}</mat-header-cell>
          <mat-cell  mat-cell *matCellDef="let element">
            <div  *ngFor="let button of actionButtons">
              <button mat-icon-button matTooltip="{{ button.tooltipMsg | translate }}" color="{{ button.color }}">
                <mat-icon>{{ button.icon }} </mat-icon>
              </button>
            </div>
          </mat-cell>
        </ng-container>

.ts I also have the method confirmDialog as seen below and three buttons that contain values from the loop above

  public confirmDialog(scenarioId: string): void {
    const dialogRef = this.dialog.open(ScenarioListDialogComponent, {
      maxWidth: '400px',
      data: { scenarioId }
    });
    dialogRef
      .afterClosed()
      .subscribe((dialogResult) => {
        this.result = dialogResult;
      })
      .unsubscribe();
  }

interface ActionButton {
  icon: string;
  tooltipMsg: string;
  color?: string;
}

  public actionButtons: ActionButton[] = [
    {
      icon: 'edit',
      tooltipMsg: 'scenarios.scenariosList.editBtnTooltipMsg',
      color: 'primary'
    },
    {
      icon: 'cloud_upload',
      tooltipMsg: 'scenarios.scenariosList.uploadBtnTooltipMsg',
      color: 'accent'
    },
    {
      icon: 'delete',
      tooltipMsg: 'scenarios.scenariosList.deleteBtnTooltipMsg',
      color: 'warn'
    }
  ];

What I am trying to accomplish is to assign the method confirmDialog to the button that has icon: 'delete' and call on that method on click. Unfortunately I am ending up assigning this method to all three buttons and I cannot seem to comprehend how ng loops work and how can I solve this.

Any help?

I tried ngIf inside ngFor but error comes up...

CodePudding user response:

Do you still want the other 2 buttons to be rendered? I'm going to assume yes. So we render all buttons with:

   (click)="button.icon === 'delete' ? confirmDialog(element.scenarioId) : ''"

But only on button, where button.icon is 'delete' we can call confirmDialog() on others it will do nothing ''.

<button
   (click)="button.icon === 'delete' ? confirmDialog(element.scenarioId) : ''"
   mat-icon-button 
   matTooltip="{{ button.tooltipMsg | translate }}" 
   color="{{ button.color }}">
   <mat-icon>{{ button.icon }} </mat-icon>
</button>

CodePudding user response:

Isnt this what you want?

        <div  *ngFor="let button of actionButtons">
          <button mat-icon-button (click)="button.icon=='delete' ? doIt():null">
            <mat-icon>{{ button.icon }} </mat-icon>
          </button>
        </div>

I have just used conditional expression as click handler.

Personally I would eg pass button model to a generic actionPerformed(b:ActionButton) and do the rest from the component code

        <div  *ngFor="let button of actionButtons">
          <button mat-icon-button (click)="buttonAction(button)">
            <mat-icon>{{ button.icon }} </mat-icon>
          </button>
        </div>


buttonAction(button:ActionButton){
   if(button.icon='delete') {doIt(); return}
}

CodePudding user response:

There are various ways to deal with this, on top of my mind I have a few:

Approach 1

  • Add helper method to existing button
<mat-icon (click)="helper(button.icon)">{{ button.icon }} </mat-icon>

In .ts file you would have the helper method

helper(icon: string):void {
 if (icon === 'delete') {
    this.confirmDialog()
 }
}

Approach 2

If you know that delete index would be last always then in your .html you can track the last element by addinglet last = last to the ngFor and then bind confirmDialog to click

<div 
 
*ngFor="let button of actionButtons; let last = last">
    <button mat-icon-button 
    matTooltip="{{ button.tooltipMsg | translate }}" 
    color="{{ button.color }}">
        <mat-icon>{{ button.icon }} </mat-icon>
        <mat-icon ngIf="last" (click)="confirmDialog()">{{ button.icon }} </mat-icon>
    </button>
</div>
  • Related