How can I remove a row from a mat table using Angular?

Having trouble implementing *ngFor in my angular mat table, seeking guidance from someone with more expertise?

I am trying to delete a row within an array using a button and display it on my table, but encountering issues. I intend to utilize *ngFor to showcase the table data, however, clicking the ADD button simply adds another empty row.

https://i.stack.imgur.com/KQd45.jpg

This is the current code snippet:

angular-table.component.html

<table mat-table *ngFor="let item of data" class="mat-elevation-z8" matSort>

    <ng-container matColumnDef="title">
        <th mat-header-cell *matHeaderCellDef>Title</th>
        <td mat-cell *matCellDef> {{item.title}} </td>
    </ng-container>

    <ng-container matColumnDef="id" id="id">
        <th mat-header-cell *matHeaderCellDef>ID</th>
        <td mat-cell *matCellDef> {{item.id}}</td>
    </ng-container>

    <ng-container matColumnDef="delete">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Test</th>
        <td mat-cell *matCellDef> 
            <mat-icon (click)="removeCart(i)" class="removeCart">close</mat-icon>
        </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

<button (click)="ADD1()">Add1</button>
<button (click)="ADD2()">Add2</button>

angular-table.component.ts

export class AngularTableComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

  amount: number;
  data: any = [];
  id: number = 2;
  title: string = 'test';

  displayedColumns: string[] = ['title', 'id', 'delete'];


  ADD1(){
    const id = this.id;
    const title = this.title;

    const newData = {
      id,
      title
    }
    this.data.push(newData);
    console.log(this.data);
   }


  ADD2(){
    const id = this.id = 7;
    const title = this.title = "Hello";

    const newData = {
      id,
      title
    }
    this.data.push(newData);
    console.log(this.data);
   }


  removeCart(index: number){
    this.data.splice(index, 1);
  }
}

I tried creating a StackBlitz, but faced challenges importing the modules. Here is the link: https://stackblitz.com/edit/add-angular-material-o2pu6c?file=src%2Fmain.ts

Appreciate any assistance!

Answer №1

The first step is to utilize

<table mat-table *ngFor="let item of data"
, which will display the table with a header but won't show any data.

To solve this, it's recommended to use MatTableDataSource.

dataSource: MatTableDataSource<any> = new MatTableDataSource<any>([]);

Next, assign your data to the data property of the dataSource.

this.dataSource.data = this.data;

Now, the table will render correctly:

<table mat-table class="mat-elevation-z8" [dataSource]="dataSource" matSort>

Also, define your columns like this:

<ng-container matColumnDef="title">
     <th mat-header-cell *matHeaderCellDef>Title</th>
     <td mat-cell *matCellDef> {{item.title}} </td>
</ng-container>

If you need to delete a row, add a button and specify the index of the row to delete it.

<ng-container matColumnDef="delete">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Test</th>
    <td mat-cell *matCellDef="let i = index"> 
        <button mat-icon-button class="removeCart" (click)="removeCart(i)" > ;
           <mat-icon>close</mat-icon>
        </button>
    </td>
</ng-container>

Check out the working demo on StackBlitz.

Answer №2

Within the "angular-table.component.html" file, you can include a button in a row to retrieve the ID:

<table mat-table *ngFor="let item of data" class="mat-elevation-z8" matSort>

    <ng-container matColumnDef="title">
        <th mat-header-cell *matHeaderCellDef>Title</th>
        <td mat-cell *matCellDef> {{item.title}} </td>
    </ng-container>

    <ng-container matColumnDef="id" id="id"">
        <th mat-header-cell *matHeaderCellDef>ID</th>
        <td mat-cell *matCellDef> {{item.id}}</td>
    </ng-container>

    <ng-container matColumnDef="delete">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Test</th>
        <td mat-cell *matCellDef> 
            <mat-icon (click)="removeCart(i)" class="removeCart">close</mat-icon>
        </td>
    </ng-container>

   <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
   <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

        <div class="example-element-description">
          <button
            mat-raised-button
            color="warn"
            (click)="handelDelete(item.id)"
          >
            Delete
          </button>
        </div>
</table>

<button (click)="ADD1()">Add1</button>
<button (click)="ADD2()">Add2</button>

To enable removal of an element from the data[] array and update the table data, add the corresponding method in your angular-table.component.ts:

export class AngularTableComponent implements OnInit {

  constructor() { }

  ngOnInit() {
    this.data = this.data.filter(element => element !== null);
  }

  amount: number;
  data: any = [];
  id: number = 2;
  title: string = 'test';

  displayedColumns: string[] = ['title', 'id', 'delete'];

constructor() { }


  ADD1(){
    const id = this.id;
    const title = this.title;

    const newData = {
      id,
      title
    }
    this.data.push(newData);
    console.log(this.data);
   }


  ADD2(){
    const id = this.id = 7;
    const title = this.title = "Hello";

    const newData = {
      id,
      title
    }
    this.data.push(newData);
    console.log(this.data);
   }

handelDelete(pId) {
// Remove the element with matching ID
this.data = this.data.filter(element => element !== pId);
  }


  removeCart(index: number){
    this.data.splice(index, 1);
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to verify if a function has completed execution and proceed to invoke another function

I am seeking to verify if a user has chosen an item from the ngFor form and then redirect them to another page upon submitting the form with the updated value. HTML: <mat-select placeholder="Treatment" [(ngModel)]="model.TreatmentA" name="TreatmentA" ...

The assertion error `args[3]` must be an integer value, but it failed to meet the requirement

Software Version: v12.19.0 Operating System Platform: Linux ayungavis 5.4.0-48-generic #52~18.04.1-Ubuntu SMP Thu Sep 10 12:50:22 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux Subsystem: Steps to Reproduce the Issue I attempted to follow the tutorial provided ...

An error in typescript involving a "const" assertion and a string array

Currently, I am diving into the world of Typescript along with React. However, an error has emerged in my path that I can't seem to figure out. It's puzzling why this issue is occurring in the first place. Allow me to elaborate below. const color ...

Error in IONIC 3: The code is unable to read the 'nativeElement' property due to an undefined value, resulting in a TypeError

I am currently learning about IONIC 3 and working on an app that utilizes the Google Maps API. However, when I try to launch my app, I encounter the following error message: inicio.html Error: Uncaught (in promise): TypeError: Cannot read property ' ...

Errors during TypeScript compilation in Twilio Functions

When I run npx tsc, I encounter the following errors: node_modules/@twilio-labs/serverless-runtime-types/types.d.ts:5:10 - error TS2305: Module '"twilio/lib/rest/Twilio"' does not export 'TwilioClientOptions'. 5 import { Twil ...

What is the best way to implement automatic generation of varying numbers of tabs?

I'm facing an issue where the number of array items determines how many tabs are required. For example, if my array includes 'dog', 'cat', and 'mouse', I need 3 tabs named 'dog', 'cat', and 'mouse ...

Issue with Ionic: The schema validation has encountered errors stating that the property 'class' is required for the data path ".builders['app-shell']"

After updating from Ionic4 to Ionic5 and attempting to run the Ionic app, I encountered a server error with the following message: [ng] Schema validation failed with the following errors: [ng] Data path ".builders['app-shell']" should have requi ...

What is the reason for recursion not producing a new object as output?

Trying to filter out nodes in a recursion function that iterates through a tree based on the registry property. function reduceNodesRegistry(source: any) { if (!source.registry) return source; return { ...source, children: s ...

Combining b2c and b2e integration through Azure Active Directory

Is there an efficient method for combining Azure AD b2c and b2e within an Angular application? Can we provide two separate buttons on the login page and redirect users based on their selection? Alternatively, could social login be utilized, keeping in mi ...

Angular select element is not functioning properly with the `addEventListener` method

My current project involves creating a table using the primeng library. The table consists of three rows and three columns, and all the data is static. Even though I am utilizing an external library, I find myself traversing the DOM directly. <p-table ...

The system encountered a TypeError: Unable to access the 'nativeElement' property as it is undefined

Hello, I am a beginner in Angular 2 and currently working on an image cropping plugin. My goal is to display the image on a canvas element. Below is my HTML code: <div class="row"> <div class="col-sm-6"> <canvas id="layout" width="40 ...

Tabs on Ionic Page

I have a mobile app built with Ionic 3 and Angular that I am currently in the process of upgrading to Ionic 6. The app does not use tabs throughout, but certain pages within the app have tab functionalities. Here is a simplified example: foo.html: <io ...

Advantages of utilizing Angular libraries compared to Angular modules within a monorepo, exploring the NX architecture

What advantages does using libraries instead of modules in Angular offer, as suggested by nx.dev for a monorepo architecture? I can see the benefits for an npm publishable feature like interfaces that another repo will use, but why should I turn a busines ...

Angular progress tracker with stages

I have been exploring ways to create a progress bar with steps in Angular 12 that advances based on the percentage of progress rather than just moving directly from one step to another. This is specifically for displaying membership levels and indicating h ...

How can you initialize Boostrap components or Materialize css in Angular 5 without using any external libraries?

I am a beginner exploring the world of Typescript and Angular. I am curious about how to initialize Bootstrap elements in an Angular-friendly manner without using the ngx-Bootstrap wrapper. For instance, if I wish to initiate a Bootstrap carousel. As per ...

Using TypeScript to deserialize JSON into a Discriminated Union

Consider the following Typescript code snippet: class Excel { Password: string; Sheet: number; } class Csv { Separator: string; Encoding: string; } type FileType = Excel | Csv let input = '{"Separator": ",", "Encoding": "UTF-8"}&ap ...

Is there a method we can use to replace fixture fields with data created during the test case to produce a dynamic payload? (Already attempted existing solution)

I am new to using Cypress and I'm wondering if there is a way to generate a dynamic payload by replacing values in a JSON file with values generated programmatically in a Cypress test. This is similar to what we do in Rest Assured by substituting %s i ...

The function res.status is not defined

Currently, I am in the process of integrating my upcoming app with Google Sheets. I have relocated the function that manages the post request to "app/api/sheets" as per the recommended documentation. import type { NextApiRequest, NextApiResponse } from &ap ...

Encountering Issues with Accessing Property

Upon trying to run my code, the console is displaying an error that I am unable to resolve. The error specifically states: "TypeError: Cannot read property 'author' of undefined." View the StackBlitz project here The error seems to be coming fr ...

Reinforced.Typings does not generate fully qualified names (FQN) for types when UseModules is set to true or false

Overview: Within my solution, I have two projects: ProjA and ProjB. In ProjA, I've defined a custom RTConfigure method to streamline the configuration process for translating C# to TypeScript using the Reinforced.Typings tool. Meanwhile, ProjB houses ...