Angular v15 Footer Component Table

In my Angular 15 project, I am attempting to correctly position and utilize the mat table with the following code snippet:

<tr mat-footer-row *matFooterRowDef="displayedColumns"></tr>
. While the displayedColumns property is functioning as expected for other parts of the table, I encounter the following error:

Cannot read properties of undefined (reading 'template')
    at MatFooterRowDef.extractCellTemplate (table.mjs:415:38)
    at table.mjs:1904:27

What additional steps do I need to take in terms of adding, removing, or importing components when using this feature? Currently, I have already imported MatTableModule.

Frustrated with the lack of clarity and accuracy in the Angular Material documentation.

Files: TS

@Component({
  selector: 'saa-prior-sales',
  templateUrl: './prior-sales.component.html',
  styleUrls: ['./prior-sales.component.css'],
  standalone: true,
  imports: [CommonModule, CurrencyPipe, MatTableModule],
})
export class PriorSalesComponent implements OnChanges {
  @Input() sales?: IVehicleDetails[]; //New Interface for Sale
  //Sort these in descending Date (table cannot be sorted)
  dataSource = new MatTableDataSource<IVehicleDetails[]>();

  displayedColumns: string[] = [
    'model',
    'style',
    'eng',
    'trans',
    'miles',
    'price',
    'date',
  ];
  ngOnChanges(changes: SimpleChanges) {
    const vehicleList = changes['sales'].currentValue;
    this.dataSource = vehicleList;
  }
}

HTML

<div
  *ngIf="dataSource"
  class="w-full p-6 mt-0 bg-white border border-gray-200 rounded-lg shadow md:mb-4 sm:mb-4 ng-star-inserted saa-green">
  <div class="p-2 mb-4 text-xl font-medium saa-blue">Prior Sales</div>
  <table mat-table [dataSource]="dataSource">
    <!-- Location -->
    <ng-container matColumnDef="model">
      <th mat-header-cell *matHeaderCellDef>Model</th>
      <td mat-cell *matCellDef="let sale">
        {{ sale.vehicle?.location }}
      </td>
    </ng-container>

    <!-- Remaining Code Stays Unchanged -->

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

The issue disappears when I remove the mat-footer-row element, but I want it to work as intended without causing any malfunctions.

Answer №1

All cells in the *matFooterRowDef must contain *matFooterCellDef within matColumnDef

<ng-container matColumnDef="date">
    <th mat-header-cell *matHeaderCellDef>Date</th>
    <td mat-cell *matCellDef="let sale">
      {{ sale.date | date }}
    </td>
    <td mat-footer-cell *matFooterCellDef>100</td> <!--  should be present if property exists in matFooterRowDef array! --> 
  </ng-container>

code

import { CommonModule } from '@angular/common';
import { Component, SimpleChanges } from '@angular/core';
import { MatTableModule, MatTableDataSource } from '@angular/material/table';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <div
  *ngIf="dataSource"
  class="w-full p-6 mt-0 bg-white border border-gray-200 rounded-lg shadow md:mb-4 sm:mb-4 ng-star-inserted saa-green">>
  <div class="p-2 mb-4 text-xl font-medium saa-blue">>Prior Sales</div>>
    <table mat-table [dataSource]="dataSource">>
      <!-- Location -->
      <ng-container matColumnDef="model">
        <th mat-header-cell *matHeaderCellDef>Model</th>
        <td mat-cell *matCellDef="let sale">
          {{ sale.vehicle?.location }}
        </td>
        <td mat-footer-cell *matFooterCellDef>100</td>
      </ng-container>

      <!-- LaneLot Column -->
       
        ...
        
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let element; columns: displayedColumns"></tr>
      <tr mat-footer-row *matFooterRowDef="displayedColumns"></tr>
    </table>
  </div>
  `,
  imports: [CommonModule, MatTableModule],
})
export class App {
  sales?: any[] = [
    {
      model: 'test',
      style: 'test',
      eng: 'test',
      trans: 'test',
      miles: 'test',
      price: 'test',
      date: 'test',
    },
  ]; //New Interface for Sale
  
  dataSource = new MatTableDataSource<any[]>();

  displayedColumns: string[] = ['model', 'style', 'eng', 'trans', 'miles', 'price', 'date'];
  
  ngOnChanges(changes: SimpleChanges) {
    const vehicleList = changes['sales'].currentValue;
    this.dataSource = vehicleList;
  }
}

bootstrapApplication(App);

stackblitz

Answer №2

It is important to include a mat-footer-cell td element for each column specified in *matFooterRowDef, even though this is not clearly outlined in the documentation. The example provided also seems to contradict this information. This lack of clarity in the documentation can be frustrating. Fortunately, I was able to find the solution on a different discussion thread: Angular Material v6 Mat-Footer - "Cannot read property 'template' of undefined"

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

Unit testing in Angular 2+ involves testing a directive that has been provided with an injected window object

Currently, I am faced with the challenge of creating a test for a directive that requires a window object to be passed into its constructor. This is the code snippet for the directive: import { Directive, ElementRef, Input, OnChanges, OnDestroy, OnInit ...

Angular 13: Issue with displaying lazy loaded module containing multiple outlets in a component

Angular version ^13.3.9 Challenge Encountering an issue when utilizing multiple outlets and attempting to render them in a lazy module with the Angular router. The routes are being mapped correctly, but the outlet itself is not being displayed. Sequence ...

is there a way to modify the background color of a div element by comparing values in javascript?

Is there a way to dynamically update the background color of a div element within a table based on values stored in a json array from a database? ...

Is it possible to create an observable with RXJS that emits only when the number of items currently emitted by the source observables matches?

I am dealing with two observables, obs1 and obs2, that continuously emit items without completing. I anticipate that both of them will emit the same number of items over time, but I cannot predict which one will emit first. I am in need of an observable th ...

Determining the size of a custom-typed array in Typescript

Can anyone explain how to find the length of a custom typed array? For example: type TMyArray = IProduct[] interface IProduct { cost: number, name: string, weight: number } So, how can we determine the length in this case: const testArr: TMyArray ...

The parameter 'host: string | undefined; user: string | undefined' does not match the expected type 'string | ConnectionConfig' and cannot be assigned

My attempt to establish a connection to an AWS MySQL database looks like this: const config = { host: process.env.RDS_HOSTNAME, user: process.env.RDS_USERNAME, password: process.env.RDS_PASSWORD, port: 3306, database: process.env.RDS_DB_NAME, } ...

Issues with the execution of Typescript decorator method

Currently, I'm enrolled in the Mosh TypeScript course and came across a problem while working on the code. I noticed that the code worked perfectly in Mosh's video tutorial but when I tried it on my own PC and in an online playground, it didn&apo ...

Directive for creating a custom loading indicator in Angular

I have created a custom Angular element directive that displays and hides a loading indicator based on a condition from a service call. The directive is used as an element within another element. While the directive itself works correctly, the issue is tha ...

What is the best way to approach writing a shared value that is utilized across multiple files in Angular?

I am currently implementing Angular for the front end of my project. One challenge I'm facing is managing a single value, such as a 'role id', that needs to be used in multiple .ts files within Angular. Can anyone suggest an efficient way ...

What is the best approach to access the reportProgress of several observables combined within a forkJoin?

I'm currently working on an Angular project where I need to upload multiple files through a form. Each file could be quite large, so I can't just do one POST request with all the files due to server size limits. It would be great if I could impl ...

Automatically choosing a radio button in a carousel using Angular

My Angular application includes the npm-hm-carousel. I am looking to automatically select the item in the center of the carousel, similar to the image provided. However, I also need to bind one of the ids to the selected item as I scroll through the carous ...

The search button in the ngx-pagination StartDate and EndDate Search Filter is unresponsive

Working with Angular-14 and ASP.Net Core-6 Web API to consume an endpoint and handle JSON responses. An example of the endpoint URL without parameters: https://localhost/MyApp/api/v1/all-merchants And when parameters are included: https://localhost/MyApp ...

Trouble with updating data in Angular 8 table

In Angular 8, I have created a table using angular material and AWS Lambda as the backend. The table includes a multi-select dropdown where users can choose values and click on a "Generate" button to add a new row with a timestamp and selected values displ ...

Creating Separate User and Admin Navigation in Angular: Step-by-Step Guide

I am facing an issue in my Angular project where I want to segregate the admin and user navigation similar to that of an e-commerce website. However, the children route is not functioning properly for the dashboard or user sections. Whenever I click on the ...

Tips for customizing the appearance of ng-bootstrap accordion

Looking to enhance the appearance of ng-bootstrap accordion with some unique fade styling. Any suggestions on how to accomplish this? ...

Which ngTagsInput version is recommended for Angular instead of AngularJs?

After discovering the ngTagsInput framework on this site, I found it to be a very comprehensive library. However, for Angular 8 users like myself, I came across the ngx-chips framework on this page. While ngx-chips seems to work, I noticed that it lacks s ...

Transfer your focus to the following control by pressing the Enter key

I came across a project built on Angular 1.x that allows users to move focus to the next control by pressing the Enter key. 'use strict'; app.directive('setTabEnter', function () { var includeTags = ['INPUT', 'SELEC ...

Issues arise with Google Cloud Builder for Angular when attempting to install Node SASS using the Cloud Builders Community image

Here are the steps I've taken so far: I have set up a Google Cloud Repository I created a Cloud Build Trigger and linked it to my GitHub account and repository, ensuring that the branch name matches exactly as ^staging$ Now, following instructions f ...

Error message in Angular Reactive Forms: Control with specified path cannot be found

My current challenge lies within the component: cabinet-clinic-form.component.ts. I am facing an issue with FormGroup validation in my clinics FormArray. Upon rendering the page, I encounter an error as shown in this screenshot. Despite attempting to dynam ...

Steps for constructing an object literal with a property designated as the `keyof` type

Struggling to articulate my question, here is a simplified code snippet outlining what I aim to accomplish. class Example<T, TId extends keyof T> { public create(id: T[TId]): T { return { [TId]: id, // Encounter an error at this point. Ob ...