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

Combining Vue with Typescript and rollup for a powerful development stack

Currently, I am in the process of bundling a Vue component library using TypeScript and vue-property-decorator. The library consists of multiple Vue components and a plugin class imported from a separate file: import FormularioForm from '@/FormularioF ...

Using ReactJS with Typescript: attempting to interpret a value as a type error is encountered (TS2749)

Currently, I am working on coding a ReactJS class using Typescript and Material-ui in a .tsx file. In one of the custom components that I have created, I need to establish a reference to another component used within this custom component. export class My ...

Determining the type relationship between two generic types when using a union

Here is the code snippet defining a React component using react-hook-form: import { type FieldPath, type FieldValues, type FieldPathValue, } from "react-hook-form"; interface FormControlRadioBoxProps< TFieldValues extends FieldValue ...

What is the best way to incorporate ng-select within a custom form controller?

I've attempted to create a stackblitz demo to illustrate my issue, but unfortunately, I couldn't make it work properly. Therefore, I'm reaching out for assistance. I have 2 components: Component 1 is a specialized form controller that encap ...

Determining interface value based on the presence of another optional interface value

I am working with an interface that looks like this: export interface IButton { label: string; withIcon?: boolean; underlined?: boolean; selected?: boolean; iconName?: string; isLink?: boolean; href?: string; onCLick?: () => void; } My question ...

Using Angular 2 to Create Nested ngFor Loops

I'm facing an issue that I can't seem to resolve. I attempted to use *ngFor in my code, but it seems that I am making a mistake with nested ngFor loops. To illustrate what I need to achieve, I ended up writing some messy code just to show the str ...

What is the ideal way to name the attribute labeled as 'name'?

When using the ngModel, the name attribute is required. But how do I choose the right name for this attribute? Usually, I just go with one by default. angular <label>First Name</label> <input type="number" name="one" [( ...

Can the getState() method be utilized within a reducer function?

I have encountered an issue with my reducers. The login reducer is functioning properly, but when I added a logout reducer, it stopped working. export const rootReducer = combineReducers({ login: loginReducer, logout: logoutReducer }); export c ...

Verifying the Presence of an Image in the Public Directory of Next JS

My TypeScript Next.js project contains a large number of images in the public folder. I am wondering if there is a way to verify the existence of an image before utilizing the <Image /> component from next/image. I have managed to achieve this using ...

Having difficulty populating a table with JSON data in Angular without encountering any error messages

After executing a query on my database, I realized that although the JSON data is correct (as confirmed through the console), the table does not populate as expected. Here is the code snippet for my component: @Component({ selector: 'app-envios&apo ...

Encountering an issue when using the Google authentication provider with Next.js version 13

I am currently working on integrating next-auth with the Google provider and Prisma in my Next.js application, but I encountered the following error: Error: Detected default export in '/MyProject/foodbrain/app/api/auth/[...nextauth]/route.ts'. Pl ...

Add an asterisk before each line of comment when working in a TypeScript file using the VS Code IDE

Within my VS Code workspace, I am using the Typescript language and would like to format my comments across multiple lines with a specific style (look out for the star character) /** *@desc any text * any text */ However, when I attempt to write a comm ...

Creating a universal parent constructor that can take in an object with keys specific to each child class

I am looking to create a base class with a constructor that allows for all the keys of the child class to be passed. However, I am facing a challenge because 'this' is not available in constructors. Here is what I hope to accomplish: class BaseCl ...

Executing a series of HTTP requests sequentially using Angular 5

I need some guidance on sending an array of HTTP requests in sequential order within my application. Here are the details: Application Entities : Location - an entity with attributes: FanZone fanZone, and List<LocationAdministrator> locationAdmins ...

Modify data in a table using Dialog Component in Angular Material

I need to implement a Material Dialog feature that allows users to update entries in a table by clicking on the "Change Status" button. Check out this functional snippet: https://stackblitz.com/edit/angular-alu8pa I have successfully retrieved data fr ...

What is the best way to loop through an object while keeping track of its value types

I have a JSON file containing UI adjustments sourced from the API: interface UIAdjustmentsJSON { logoSize: number; themeColor: string; isFullScreen: boolean; } To simplify things, let's utilize a static object: const adjustments: UIAdjust ...

Error TS2307 - Module 'lodash' not found during build process

Latest Update I must apologize for the confusion in my previous explanation of the issue. The errors I encountered were not during the compilation of the Angular application via Gulp, but rather in the Visual Studio 'Errors List'. Fortunately, I ...

Tips for passing the indexes of an array within nested ngFor loops in Angular

I have a 2D grid in my component that is created using nested ngFor loops, and I want to make certain grid elements clickable under specific conditions so they can call a function. Is there a way for me to pass the index of the clicked array element to the ...

"Enhance your forms with RadixUI's beautiful designs for

New to Radix UI and styling components, I encountered difficulties while trying to adapt a JSX component to Radix UI: Utilizing Radix UI Radio Groups, I aim to style my component similar to this example from Hyper UI with grid layout showing stacked conte ...

Is there a way to simulate AWS Service Comprehend using Sinon and aws-sdk-mock?

As a newcomer to Typescript mocking, I am trying to figure out how to properly mock AWS.Comprehend in my unit tests. Below is the code snippet where I am utilizing the AWS Service Comprehend. const comprehend = new AWS.Comprehend(); export const handler ...