Angular component experiencing difficulty sorting a column sent from parent component to child component

I'm currently facing an obstacle while trying to pass a column from a parent component to a child component in Angular. The issue arises when attempting to sort the column. Below is the code snippet:

Parent component

<table-sorting-example matSort>
  <ng-container matColumnDef="another">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Another</th>
    <td mat-cell *matCellDef="let element">{{element.another}}</td>
  </ng-container>
</table-sorting-example>

Child component

<table mat-table [dataSource]="dataSource" matSort>
  <ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Position</th>
    <td mat-cell *matCellDef="let element">{{element.position}}</td>
  </ng-container>

  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
    <td mat-cell *matCellDef="let element">{{element.name}}</td>
  </ng-container>

  <ng-container matColumnDef="weight">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Weight</th>
    <td mat-cell *matCellDef="let element">{{element.weight}}</td>
  </ng-container>

  <ng-container matColumnDef="symbol">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Symbol</th>
    <td mat-cell *matCellDef="let element">{{element.symbol}}</td>
  </ng-container>

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

Child Component TS file

import {
  AfterViewInit,
  Component,
  ContentChildren,
  QueryList,
  ViewChild,
} from '@angular/core';
import { MatSort, Sort } from '@angular/material/sort';
import {
  MatColumnDef,
  MatTable,
  MatTableDataSource,
} from '@angular/material/table';

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
  another: string;
}
const ELEMENT_DATA: PeriodicElement[] = [
  { position: 5, name: 'Boron', weight: 10.811, symbol: 'B', another: 'A' },
  { position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C', another: 'B' },
  { position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N', another: 'C' },
  { position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O', another: 'D' },
  { position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F', another: 'E' },
  { position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne', another: 'F' },
];
/**
 * @title Table with sorting
 */
@Component({
  selector: 'table-sorting-example',
  styleUrls: ['table-sorting-example.css'],
  templateUrl: 'table-sorting-example.html',
})
export class TableSortingExample implements AfterViewInit {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = new MatTableDataSource(ELEMENT_DATA);

  @ViewChild(MatTable) myTable: MatTable<PeriodicElement>;
  @ViewChild(MatSort) sort: MatSort;
  @ContentChildren(MatColumnDef) private customCols: QueryList<MatColumnDef>;

  constructor() {}

  ngAfterViewInit() {
    this.dataSource.sort = this.sort;
    for (let col of this.customCols) {
      this.myTable.addColumnDef(col);
      this.displayedColumns.push(col.name);
    }
  }
}

Sorting works as expected on columns except for the "another" column. I have explored the documentation and other resources to no avail. Any insights on why the sorting isn't functioning on the "another" column and how I could resolve it would be greatly appreciated.

You can access the complete code on stackblitz

Answer №1

To incorporate the customCols into the material table, you can use the addColumnDef method. It seems that you may need to implement a similar approach for sorting custom columns. Have you considered utilizing the register method with MatSort? Perhaps something along the lines of:

for (let column of this.customCols) {
  this.myTable.addColumnDef(column);
  this.matSort.register({id: column.name, start: 'desc', disableClear: false});
  this.displayedColumns.push(column.name);
}

Answer №2

The child component must also be informed of any sorting changes made within the parent component.

If we were to use the matSortChange event in the child component, we would realize that it does not respond to these changes. This is because we have defined two separate instances of MatSort in the code.

Check out my example, which demonstrates how to update the dataSource sorting object through @Input communication: https://stackblitz.com/edit/sku9pd-m6oc6u?file=src%2Fapp%2Ftable-sorting-example.ts

  1. Changes in the parent component:

HTML:

  • Adding a matSortChange event listener and passing its result to the onSortChange function,
  • Declaring a sortChange input and passing its result to the sortEvent property.

TYPESCRIPT:

  • Declaring the sortEvent property,
  • Defining the onSortChange method to assign the event result to the sortEvent property.
  1. Changes in the child component:

TYPESCRIPT:

  • Declaring a sortChange @Input setter to update the dataSource.sort instance based on the parent component's sorting state.

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

Tips for ensuring radiobuttons are defaulted to unchecked within a shared form group in Angular 2 and beyond

The radio buttons are linked to data from the database (Web-API). Below are my complete code snippets: component.html <!-- list of Questions --> <div formArrayName="questions"> <!-- <div *ngFor="let que of Questions; let ...

What is the process for removing the Angular IDE plugin from Eclipse Oxygen?

After using the free license for 8 days, I found myself needing to continue working. My first attempt at uninstalling Angular-IDE through Eclipse Marketplace Installed screen was unsuccessful. Next, I tried removing Webclipse, but this also did not ...

Creating a personalized audio player using HTML

I have created a design for an audio player that I would like to implement using the HTML audio player element. https://i.sstatic.net/vJpGg.jpg When I tried <audio></audio>, it just displayed the default player: https://i.sstatic.net/nyNj8.j ...

Troubleshooting Bootstrap select box design discrepancies

Currently revamping a website and encountered an unusual issue with select boxes. There seems to be an overlapping white space where the option values should be. Here's a visual reference: View Image of Select Box Issue Utilizing Bootstrap for the re ...

Error in Angular 11: Unspecified parameter in the URL

I've been working on passing a URL parameter received from a GET request to the Contracts component. However, when visiting the Contracts component in the URL, the passed parameter appears as undefined. Here's what I have tried so far: In my app ...

Update an item's precise orientation in relation to the global axis

Update: Included a jsfiddle for clarification: JSFiddle I am working with an object (a cube) in a scene and my objective is to provide it with 3 angles that represent its orientation in the real world. These angles are measured against the X, Y, and Z ax ...

Using Node.js to retrieve child processes associated with a daemon and terminate them

I am attempting to create a node application that allows me to send the command kill -9 to all child processes of a single daemon. Just to clarify, there is one daemon running on our server. Upon startup, it initiates a process for communicating with clie ...

Ways to programmatically move from one step to another in ngx-admin nebular stepper

Currently utilizing the nebular ngx-admin template, I have encountered some challenges with the nebular stepper. Within one component, I have implemented four steps. In the component file, I have utilized Nebular API's methods: @ViewChild("stepp ...

Error Encountered During JavaScript Form Validation

Currently, I am troubleshooting a website that was created by another developer. There is a form with JavaScript validation to ensure data is accurately entered into the database. However, I am puzzled as to why I keep receiving these alert messages. Pleas ...

Send form information using AJAX response

I have successfully implemented a feature where I load an iframe into a div with the id of #output using AJAX. This allows me to play videos on my website. jQuery( document ).ready( function( $ ) { $( '.play_next' ).on('click', fun ...

Tips for exporting a module from a parent module to a child module

In my HomeModule, I included imports for SharedModule with Angular Material and ToolbarModule. I am wondering how I can import SharedModule only once in HomeModule and have it accessible to all child modules that require it. Here is the code snippet: @NgM ...

The ajax success error function does not trigger in jQuery

Hey, check out my code below: <html> <head> <script src="http://code.jquery.com/jquery-1.8.0.min.js"> </script> </head> <body> <form id="foo"> <label for="bar">A bar</label> <input id ...

Can you list out the directives that are responsible for generating child scopes in AngularJS?

I recently discovered that when using ng-if, it actually creates a child scope, leading to some confusion on my end. I'm curious about the reasons or benefits behind ng-if's scope creation. Can you also tell me which other built-in directives cre ...

Issue: Module 'xml2json' not found

Encountered an error while running my project package. When I tried to install the necessary packages using npm install xml2json I still encountered another error below. Can anyone provide suggestions or ideas on how to resolve this issue? D:\xa ...

vue implementing autoscroll for long lists

I am looking to implement an autoscrolling log feature on my webpage that is dynamically fetched from a REST endpoint. To handle the potentially large size of this log, I decided to use vue-virtual-scroll-list. Additionally, I wanted the log to automatical ...

Having trouble uploading the file to IPFS: Encounter an issue with HTTPError: project id is mandatory

Currently in the process of developing a basic DApp for sharing chats, with similarities to Twitter but based on a smart contract. I am utilizing hardhat and running my application on localhost. While implementing the feature for users to upload a profile ...

A simple way to verify which option has been chosen has been altered

I am examining the code snippet below: <select class="select" id="choice-item" aria-invalid="false"> <option value="#opt0" selected="selected">32 bits</option> <option value="#opt1">64 bits</option> </select> M ...

Typescript: Removing specific types from a type

In my quest to filter out specific types from a group, I encountered a challenge with exclusion. Take for instance the scenario below: type RemoveUndefined<T> = T extends undefined | infer R ? R : T; type numbersOnly = RemoveUndefined<undefined | ...

Having trouble with querySelector or getElementById not functioning properly?

Currently, I am in the midst of developing an experimental web application that features a quiz component. For this project, I have implemented a Python file to handle the questions and quiz functionalities. However, I have encountered an issue with the Ja ...

Combining duplicate objects in a JavaScript array

I am looking to identify duplicates by country code and merge them into a single object The array structure is: [{...},{...}] Objects {Country_Code: "RU", Country: "Russia", Provider: "Shell1", Price: "0.123"}, {Country_Code: "EN", Country: "Russia", P ...