Usage of $event.stopPropagation() in Angular

Supose we have a table and on row when we click it opens a form or edit view or whatever.

we have an action column where we put buttons to delete popup or whatever

so when we click in the buttons in action column, it fires both the popup and the default link or action which is set for the row.

to prevent this behavior I used:  (click)=”openPreview(id); $event.stopPropagation()”

here is the full code:

component.ts:

import { Component, OnInit, ViewChild } from “@angular/core”;
import { MatTableDataSource, MatSort, MatPaginator } from “@angular/material”;
//———dialog——————/
import {
  MatDialog,
  MatDialogRef,
  MAT_DIALOG_DATA
} from “@angular/material/dialog”;
import {
  CustomBox,
  DialogComponent
} from “../../shared/dialog/dialog.component”;
//———service——–//
import { NewsfeedService } from “../../services/newsfeed.service”;
import { INewsfeed } from “../../models/newsfeed.model”;
import { MatSnackBar, MatSnackBarConfig } from ‘@angular/material/snack-bar’;
import {Router} from ‘@angular/router’;
export interface PeriodicElement {
  title: string;
  headline: string;
  publishDate?: string;
}
@Component({
  selector: “app-newsfeed”,
  templateUrl: “./newsfeed.component.html”,
  styleUrls: [“./newsfeed.component.css”]
})
export class NewsfeedComponent implements OnInit {
  ELEMENT_DATA;
  //dataSource;
  News;
  NewsfeedList: INewsfeed[];
  //@ViewChild(MatSort, { static: true }) sort: MatSort;
  @ViewChild(MatSort) sort: MatSort;
  //@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
  @ViewChild(MatPaginator) paginator: MatPaginator;
  displayedColumns: string[] = [
    “Status”,
    “Title”,
    “Headline”,
    “Publishdate”,
    “ModifiedBy”,
    “delete”
  ];
  dataSource: MatTableDataSource<any>;
  constructor(
    private service: NewsfeedService,
    public dialog: MatDialog,
    private _snackBar: MatSnackBar,
    private router: Router) { }
  ngOnInit() {
    this.refreshData();
    this.paginator.pageSize = 10;
  }
  refreshData() {
    this.service.getAllNewsfeed().subscribe((newsfeed: INewsfeed[]) => {
      console.log(newsfeed)
      this.NewsfeedList = newsfeed;
      this.ELEMENT_DATA = newsfeed;
      this.dataSource = new MatTableDataSource(this.ELEMENT_DATA);
      this.dataSource.sort = this.sort;
      this.dataSource.paginator = this.paginator;
    },
    (error)=>{
        this.ErrorDialog(“Server Error”,”Error Connecting to Server”,”Close”,”Refresh”)
      }
    );
  }
  deleteNewsfeed(id) {
    console.log(id);
    if (id > 0) {
      this.service.deleteNewsfeed(id).subscribe((res)=>{
          if(res){
            this.MessageBox(‘Record deleted successfully’,’X’,5000,’SuccessMessage’);
            // setTimeout(()=>{
            //   //this.callNext();
            //   this.callRedirect(‘../iap/newsfeed’,4000);
            // },5000)
            this.callNext(4000);
          }else{
            this.MessageBox(‘Error Deleting’,’X’,5000,’ErrorMessage’);
          }
        },
        (error)=>{
          this.ErrorDialog(“Server Error”,”Error Connecting to Server”,”Close”,”Refresh”);
        }
      );
    }
  }
  applyFilter(filterValue: string) {
    this.dataSource.filter = filterValue.trim().toLowerCase();
  }
  //————–dialog——-//
  openDialog(id): void {
    const message = `Are you sure you want to delete?`;
    let no = “No”;
    let yes = “Yes”;
    const resDialog = new CustomBox(“Confirm Action”, message,no,yes);
    const dialogRef = this.dialog.open(DialogComponent, {
      maxWidth: “600px”,
      data: resDialog
    });
    dialogRef.afterClosed().subscribe(dialogResult => {
      if (dialogResult) {
        this.deleteNewsfeed(id);
      }
    });
  }
  public openSnackBar(message: string, action: string) {
    this._snackBar.open(message, action, {
      duration: 4000,
      verticalPosition: ‘top’,
      horizontalPosition: ‘center’,
    });
  }
  public  MessageBox(message: string, action: string, duration:number,BoxColorClass) {
    this._snackBar.open(message, action, {
      duration: duration,
      verticalPosition: ‘top’,
      horizontalPosition:’center’,
      panelClass: [BoxColorClass]
    });
  }
  ErrorDialog(dialogHeading,messages:string,no,yes): void {
    const resDialog = new CustomBox(dialogHeading, messages,no,yes);
    const dialogRef = this.dialog.open(DialogComponent, {
      maxWidth: “600px”,
      data: resDialog
    });
    dialogRef.afterClosed().subscribe(dialogResult => {
      if (dialogResult) {
       this.callNext(200);
      }
    });
  }
  callNext(timeout){
    setTimeout(()=>{
      this.refreshData();
    },timeout);
  }
  /*—-Work to be done as planned—–*/
  callRedirect(route,time){
    setTimeout(()=>{
      this.router.navigate([route]);
    },time)
  }
  openPreview(id): void {
    const message = `Are you sure you want to delete?`;
    let no = “No”;
    let yes = “Yes”;
    const resDialog = new CustomBox(“Confirm Action”, message, no, yes);
    const dialogRef = this.dialog.open(DialogComponent, {
      maxWidth: “600px”,
      data: resDialog
    });
    dialogRef.afterClosed().subscribe(dialogResult => {
      if (dialogResult) {
        this.deleteNewsfeed(id);
      }
    });
  }
}
=========================================================================
component html
<div class=”admin-announcement-container”>
  <mat-card class=”main-container”>
    <mat-card-title>
      <h1 class=”card-title”>Newsfeed</h1>
      <div class=”actions-box”>
        <mat-form-field appearance=”outline” class=”search-bar”>
          <input matInput #search (keyup)=”applyFilter($event.target.value)” maxlength=”256″ placeholder=”Search” />
          <mat-icon matSuffix>search</mat-icon>
          <mat-hint align=”start”>Example: Title, Last Modified By </mat-hint>
        </mat-form-field>
        <mat-card-actions>
          <button mat-stroked-button class=”is-rounded” color=”accent” [routerLink]=”[‘../newsfeed/addnews’]”>
            <mat-icon>add</mat-icon> <span>Add New</span>
          </button>
          <button class=”is-rounded” color=”accent” mat-stroked-button [routerLink]=”[‘../preview’]”>
            <mat-icon>remove_red_eye</mat-icon> <span>Preview</span>
          </button>
        </mat-card-actions>
      </div>
    </mat-card-title>
    <mat-card-content class=”mat-elevation-z8″>
      <table mat-table [dataSource]=”dataSource” matSort>
        <!— Note that these columns can be defined in any order.
                              The actual rendered columns are set as a property on the row definition” –>
        <!– Weight Column –>
        <ng-container matColumnDef=”Status”>
          <th mat-header-cell *matHeaderCellDef mat-sort-header>Status</th>
          <td mat-cell *matCellDef=”let element”>
            <!– <span class=”dot” [ngClass]=”{
                        ‘dot-active’: element.Name == ‘Published’,
                        ‘dot-closed’: element.Name == ‘Closed’
                      }”>
            </span> –>
            <table>
              <tr>
                <td>
                    <!– <mat-icon class=”delete-box” (click)=”openDialog(element.NewsfeedID); $event.stopPropagation()” title=”Published” class=”icon-green”>check_circle_outline</mat-icon> –>
                    <mat-icon (click)=”openPreview(id); $event.stopPropagation()”  *ngIf=”element.Name == ‘Published’; else isDraft” class=”icon-green”>remove_red_eye</mat-icon>
                  <ng-template #isDraft>
                    <mat-icon (click)=”openPreview(id); $event.stopPropagation()”  *ngIf=”element.Name == ‘Draft’; else isClosed”>remove_red_eye</mat-icon>
                    <!– <mat-icon class=”delete-box” (click)=”openDialog(element.NewsfeedID); $event.stopPropagation()” title=”Draft”>info</mat-icon> –>
                  </ng-template>
                  <ng-template #isClosed>
                    <mat-icon (click)=”openPreview(id); $event.stopPropagation()” class=”icon-red”>remove_red_eye</mat-icon>
                    <!– <mat-icon class=”delete-box” (click)=”openDialog(element.NewsfeedID); $event.stopPropagation()” title=”Draft”>info</mat-icon> –>
                  </ng-template>
                </td>
                <td>
                  {{ element.Name }}
                </td>
              </tr>
            </table>
          </td>
          <!– <ng-container matColumnDef=”Published”>
            <th mat-header-cell *matHeaderCellDef mat-sort-header>Published</th>
            <td mat-cell *matCellDef=”let element”>
                <div *ngIf=”element.IsPublished; else isDraft”>
                  <mat-icon class=”delete-box” (click)=”openDialog(element.NewsfeedID); $event.stopPropagation()” title=”Published” class=”icon-green”>check_circle_outline</mat-icon>
                  <mat-icon class=”icon-green”>remove_red_eye</mat-icon>
                </div>
                <ng-template #isDraft>
                  <mat-icon >remove_red_eye</mat-icon>
                  <mat-icon class=”delete-box” (click)=”openDialog(element.NewsfeedID); $event.stopPropagation()” title=”Draft”>info</mat-icon>
                </ng-template>
            </td>
          </ng-container> –>
        </ng-container>
        <!– Position Column –>
        <ng-container matColumnDef=”Title”>
          <th mat-header-cell *matHeaderCellDef mat-sort-header>Title</th>
          <td mat-cell *matCellDef=”let element”>{{ element.Title }}</td>
        </ng-container>
        <!– Name Column –>
        <ng-container matColumnDef=”Headline”>
          <th mat-header-cell *matHeaderCellDef mat-sort-header>Headline</th>
          <td mat-cell *matCellDef=”let element”>{{ element.Headline }}</td>
        </ng-container>
        <ng-container matColumnDef=”Publishdate”>
          <th mat-header-cell *matHeaderCellDef mat-sort-header>
            Publish Date
          </th>
          <td mat-cell *matCellDef=”let element”>
            {{ element.Publishdate |  date: ‘shortDate’}}
          </td>
        </ng-container>
        <ng-container matColumnDef=”ModifiedBy”>
          <th mat-header-cell *matHeaderCellDef mat-sort-header>
            Modified By
          </th>
          <td mat-cell *matCellDef=”let element”>{{ element.ModifiedBy }}</td>
        </ng-container>
        <ng-container matColumnDef=”delete”>
          <th mat-header-cell *matHeaderCellDef mat-sort-header>Delete</th>
          <td mat-cell *matCellDef=”let element”>
              <mat-icon class=”delete-box” (click)=”openDialog(element.NewsfeedID); $event.stopPropagation()”>delete_outline</mat-icon>
          </td>
        </ng-container>
        <tr mat-header-row *matHeaderRowDef=”displayedColumns”></tr>
        <tr mat-row *matRowDef=”let element; columns: displayedColumns” [routerLink]=”[‘/content/newsfeed2/addnews/’, element.NewsfeedID]”></tr>
      </table>
      <mat-paginator [pageSizeOptions]=”[5, 10, 20, 50, 100]” showFirstLastButtons> </mat-paginator>
    </mat-card-content>
  </mat-card>
</div>