Angular material table footer calculations

I am currently utilizing Angular Material Table version 8.2.3 to generate multiple tables from a TypeScript definition. The majority of these tables are related to numerical data, requiring me to display totals in the footer section. However, I am facing an issue as the examples provided on the official material page only showcase single-column tables and do not address how to handle calculations for multiple columns. I am seeking a solution to dynamically calculate the sum of a column. Below is the code snippet that I have attempted unsuccessfully:

https://i.sstatic.net/axPZp.png

<table mat-table [dataSource]="dataSource" matSort matSortActive="Date" matSortDisableClear="true">

    <ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>{{ column.header }}</th>
        <td mat-cell *matCellDef="let row">{{ column.cell(row) }}</td>
        <td mat-footer-cell *matFooterCellDef> {{this.dataSource.data.reduce((data, val) => data+= val.cell(row), 0) </td>
    </ng-container>

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

Answer №1

Your syntax for string interpolation is incorrect.

You forgot to include }} at the end of your code.

Here is the corrected template:

<table 
  mat-table 
  [dataSource]="dataSource" 
  matSort 
  matSortActive="Date" 
  matSortDisableClear="true">

  <ng-container 
    *ngFor="let column of columns" 
    [matColumnDef]="column.columnDef">
    <th 
      mat-header-cell 
      *matHeaderCellDef 
      mat-sort-header>
      {{ column.header }}
    </th>
    <td 
      mat-cell 
      *matCellDef="let row">
      {{ column.cell(row) }}
    </td>
    <td 
      mat-footer-cell 
      *matFooterCellDef>
      {{ dataSource.data.reduce((data, val) => data+= val.cell(row), 0) }} 
    </td>
  </ng-container>

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

You may need to make the dataSource public in order to access it in the template.

Instead of exposing the entire dataSource, consider making only the data property public if it's a dependency in your Component.

Create a property like this:

data = this.dataSource.data.reduce((datum, val) => datum+= val.cell(row), 0);

When interpolating the result, use the following:

<td
  mat-footer-cell
  *matFooterCellDef>
  {{ data }} 
</td>

PS - Be cautious about calling methods in Data Binding Syntax as it can impact performance significantly.

For more information on the effects of calling methods in data binding syntax, refer to this thread:

Angular Performance: DOM Event causes unnecessary function calls

Answer №2

It seems like in the instance you provided, there was an oversight with closing the {{ tag within the

<td mat-footer-cell *matFooterCellDef> {{this.dataSource.data.reduce((data, val) => data+= val.cell(row), 0) </td>

You have the option to invoke a function from the template itself to compute the sum of a particular column. Here is an example:

<td mat-footer-cell *matFooterCellDef> {{calculateSum()}} </td>

And then in the .ts file:

calculate() {
  // perform calculation

  return result;
}

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

How can I define Record values in Typescript based on their specific keys?

I am working on creating a custom data structure that allows me to store values with string keys within the union string | number | boolean: type FilterKey = string; type FilterValue = string | number | boolean; type Filters<K extends FilterKey, T exten ...

import component dynamically from object in Next.js

Currently, I have a collection of components that I am aiming to dynamically import using next/dynamic. I'm curious if this is achievable. Here's the object in interest: // IconComponents.tsx import { Tick, Star } from 'components ...

Having trouble resolving the typescript package while integrating with another module

Attempting to develop a basic npm package with TypeScript and bundle it using webpack. When trying to use the package in another module, such as a react application named 'module A.' Within module A, the 'myLibrary' package is installe ...

The system encountered a syntax error: an unexpected token was found in the JSON at position 508

I encountered an issue with the following error message: ERROR SyntaxError: Unexpected token in JSON at position 508. I am seeking clarification on this matter and would appreciate any assistance in identifying where I may be making a mistake. Below is ...

The function is unable to access the 'FacebookAuthProvider' property as it is undefined

I'm having trouble using Angular Firebase to connect with Facebook. I keep encountering this error: AppComponent.html:2 ERROR TypeError: Cannot read property 'FacebookAuthProvider' of undefined at AuthService.signInWithFacebook (auth.servic ...

Activate a different link when one is clicked in the Angular framework

I am working on a sidebar that contains the following elements: <ul class="nav nav-pills flex-column"> <li class="nav-item collapsed side" data-toggle="collapse" data-target="#home" > <a class="nav-link" routerLinkActive="a ...

What is the best way to utilize an "as" property in TypeScript when forwarding props to a component?

I am currently working on creating a collection of components, and I require some of them to have the option of a customizable tag name. For instance, there are times when what seems like a <button> is actually an <a>. Therefore, I would like t ...

Solutions for repairing data storage variables

I am trying to access the value dogovor from session_storage and assign it to variable digi. However, I seem to be encountering an issue with this process. Can anyone help me identify where I am going wrong? loadCustomer(){ return new Promise(resolve =& ...

Oops! The type '{}' is lacking the properties listed below

interface Human { firstName: string; lastName: string; } let human1: Human = {}; human1.firstName = "John" human1.lastName = "Doe" Upon declaring human1, an error pops up: Type '{}' is missing the following properties from type Human ...

Unit test does not show the PrimeNG menubar start directive

Currently, I am in the process of writing Jasmine tests for my component which includes PrimeNG's menubar. Within this component, I am utilizing the start template directive in the following manner: <p-menubar id='menubar' [model]='i ...

Constructor not executing when using Object.create

Attempting to instantiate a class within a static method, I am using Object.create(this.prototype), which appears to be functioning correctly. Nonetheless, when I check the console, my property items is showing as undefined. The base class called model lo ...

Troubleshooting the "Cannot read properties of undefined" error in Angular 11 while managing API data

When attempting to retrieve data from an API and store it in an object (model) for logging in the console, it consistently returns undefined. The same issue occurs when attempting to use the data in HTML with databinding, resulting in undefined values as w ...

When the Image Icon is clicked, the icon itself should become clickable and trigger the opening of a popup Dialogue Box for uploading a new image

When I click on the image icon, it should be clickable and a popup dialogue box will open to upload a new image. Check out this sample image for reference. Any help on this would be greatly appreciated. Thanks in advance. <div class="d-flex align-ite ...

The function ValueChange remains uninvoked

Query: The issue is that valueChanges is only triggered for the entire form and not for specific controllers. Although this approach works, it returns the complete object. public ngOnInit(): void { this.form.createWagonBodyForm(); ...

The installation failed due to an unresolved dependency when running npm install

Upon performing a git clone, I encountered this error with my project after running npm install: npm ERR! code ERESOLVE npm ERR! npm ERR! While resolving: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6e0f1e1e43081c01001a0b000 ...

Angular2 and Firebase App unable to Compile due to TypeScript Issue

Latest Update: The recent issue causing the app to crash upon launch has been successfully resolved. Interestingly, it was not due to TypeScript compilation errors. In the Git repository's main.ts file, all that was needed was a simple line change: ...

Guide to dynamically load external JavaScript script in Angular 2 during runtime

Currently, I am integrating Twitter digits for authentication purposes. To implement this feature, a small .js script needs to be downloaded and initialized. The recommended approach is to directly fetch the file from the Twitter server. In order to succe ...

Instead of relying on Vue TypeScript, we are leveraging IntelliJ with TypeScript 5.0.3 to compile our Vue project

My current version of IntelliJ IDEA is 2023.1 (Ultimate Edition) Build #IU-231.8109.175, released on March 28, 2023. I am facing an issue where my project fails to compile using "Vue TypeScript", resulting in some type mismatches being overlooked. In the ...

Encountering an issue connecting to the backend server for the

I am attempting to make a POST request from my Angular 2 frontend to my Spring backend, but I am encountering an error. The error message: GET http://localhost:8080/loginPost 405 () Failed to load http://localhost:8080/loginPost: No 'Access-Control ...

Having trouble with the ag-grid demo - grid not displaying as intended

Struggling to wrap my head around the "ag-grid" Typescript grid component for use in my Angular 6 applications. The website seems promising, but I am having trouble getting their "Getting Started" demo to function on my setup. I followed all the setup st ...