Sorting the table in Angular Material is proving to be a challenge

I'm attempting to organize data within an Angular table by utilizing the MatSortModule. Unfortunately, the sorted table is not functioning correctly. Below is the provided code:

main.module.ts

import { MatTableModule, MatSortModule } from '@angular/material';

@NgModule({
  declarations: [
    MainComponent
  ],
  imports: [
    CommonModule,
    MatTableModule,
    MatSortModule,
  ],
  providers: []
})
export class MainModule { }

main.component.ts

import { Component, OnInit, AfterViewInit, ViewChild } from '@angular/core';
import { OrderBook } from '../core/order-book/order-book.model';
import { OrderBookService } from '../core/order-book/order-book.service';
import { MatSort, MatTableDataSource } from '@angular/material';

@Component({
  selector: 'app-main',
  templateUrl: './main.component.html',
  styleUrls: ['./main.component.css']
})

export class MainComponent implements OnInit {
  displayedColumns: string[] = ['Quantity', 'Rate'];
  orderBook: OrderBook;
  dataSource;
  constructor(private orderBookService: OrderBookService) { }

  @ViewChild(MatSort) sort: MatSort;

  ngOnInit() {
    this.getTransfers();
  }
  AfterViewInit() {
    this.dataSource.sort = this.sort;
  }

  private getTransfers(): void {
    const currency1 = 'BTC';
    const currency2 = 'LTC';
    this.orderBookService.getOrderBookBittrex(currency1, currency2)
      .subscribe(orders => {
        this.orderBook = orders;

this.dataSource = new MatTableDataSource(orders.result.buy as {}[]);

      });
  }
}

main.component.html

<table mat-table [dataSource]="orderBook?.result.buy" matSort matSortActive="Quantity" matSortDirection="asc" matSortDisableClear class="mat-elevation-z8">

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

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

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

My service order-book.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { OrderBook } from './order-book.model';


@Injectable({
    providedIn: 'root',
  })
export class OrderBookService {
    constructor(private httpClient: HttpClient) {

    }
    getOrderBookBittrex(currency1: string, currency2: string): Observable<OrderBook> {
        const url = `/api/getorderbook?market=${currency1}-${currency2}&type=both`;
        return this.httpClient.get<OrderBook>(url);
    }
}

And the models:

order-book.model.ts

import { BuyAndSell } from './buy-and-sell.model';

export interface OrderBook {
    success?: boolean;
    message?: string;
    result?: BuyAndSell;
}

buy-and-sell.model.ts

import { QuantityRate } from './quantity-rate.model';

export interface BuyAndSell {
    buy?: QuantityRate;
    sell?: QuantityRate;
}

buy-and-sell.model.ts

export interface QuantityRate {
    Quantity?: Number;
    Rate?: Number;
}

Although sorting icons are displayed on headers, the table data remains unaltered after clicking. I suspect the issue lies in converting orders.result.buy into an object compatible with the table. As mentioned in main.component.ts, MatTableDataSource only accepts {}[] format. Any suggestions on resolving this?

Answer №1

There are various ways to provide data to MatTableDataSource, contrary to the statement that it only accepts {}[] format:

dataSource = new MatTableDataSource();

this.orderBookService
       .getOrderBookBittrex(currency1, currency2)
       .subscribe(
           orders => { this.datasource.data = orders;}

Alternatively:

    dataSource = new MatTableDataSource(orders)

It is also recommended to set the datasource.sort AfterViewInit rather than OnInIt. Check out this example in the StackBlitz

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

Guide on navigating to a specific page with ngx-bootstrap pagination

Is there a way to navigate to a specific page using ngx-bootstrap pagination by entering the page number into an input field? Check out this code snippet: ***Template:*** <div class="row"> <div class="col-xs-12 col-12"> ...

Creating a universal wrapper function to serve as a logging tool?

Currently, I am working on a generic JS function that can wrap any other function. The purpose of this wrapper is to execute the wrapped function, log the input and output events, and then return the output for "transparent" logging. However, as I attempt ...

What is the correct way to specify the type in my functional component?

I was trying to define the type in my component in a different way, I know it can be done using classes but is there a way to achieve this with functional components without exporting the interface? Despite my extensive research, I couldn't find any r ...

When using Angular2, I have found that I am unable to extract the body data from JSONP responses. However, I have discovered that this issue

Initially, I developed the SERVER using spring-boot framework. The code for this looks like: public class App { @RequestMapping("/") @ResponseBody String home(HttpServletRequest request) { String aa=request.getParameter("callback"); System.out.pri ...

Unable to utilize class identifiers in TypeScript because of 'incompatible call signatures' restriction

Following the execution of relevant yarn add commands, the following lines were added to the packages.json: "@types/classnames": "^2.2.7", "classnames": "^2.2.6", Subsequently, I incorporated these lines into my typescript files: import * as classnames ...

When working with TypeScript for initial data, you have the choice between using interface types or class types. Which approach is the

When working with initial data in TypeScript, you have the option to use either an interface type or a class type. Which approach is preferable? export interface Item{ text: string, value: number } itemModel: ItemComboBox = { value:'valu ...

I'm encountering difficulties utilizing ternary operators in TypeScript

I am struggling with ternary operators in TypeScript and need help understanding the issue. Please review the code below: const QuizQuestionContainer = ({ qa }: QuizQuestionContainerPropsType) => { const { question, option1, option2, option ...

Having trouble retrieving data from mongo db collection - data not found

For my eCommerce application, I am using MongoDB and Angular. The requirement is to retrieve items under each user in the cart. However, when trying to fetch the data using the object ID as a reference, it seems unable to find any data from the database. ...

Using the Vuex Module Decorator: A guide on accessing the store from a module

Recently, I've been playing around with the vuex module decorator in order to maintain good TypeScript practices in my vuex stores. However, I'm facing issues when trying to access the store without encountering type definition problems. My setu ...

What is the best way to include generic HTML content in an Angular 2 component?

I am looking to design a versatile modal component that can accommodate various elements, ranging from text to images and buttons. If I were to implement something like the following: <div class="Modal"> <div class="header"></div> ...

Tips for sending props, state, or arguments to a TypeScript React component

Hey there, total newbie here... I'm currently working on a school project and I've hit a bit of a roadblock... I'm attempting to pass some props from one component to another, but for some reason, it's not working properly. The goal ...

Tips on utilizing boolean assignment in a ternary operator with an optional property that is an array in TypeScript

I'm trying to determine the value of an object property based on whether an optional prop is an array. Here's the scenario: const requestingMultipleDevices = Array.isArray(deviceIds); Then I have this object structure: { data: requestingM ...

Angular's detectChanges function does not trigger the ngDoCheck method

When I run cdr.detectChanges() in a nested child component (Child1) which has a parent and another nested child component (Child2), only ngDoCheck is invoked in Child2. Why doesn't it invoke DoCheck in the current component (Child1) as well? How can I ...

Error message: WebStorm shows that the argument type {providedIn: "root"} cannot be assigned to the parameter type {providedIn: Type<any> | "root" | null} and InjectableProvider

Transitioning my app from Angular v5 to v6 has presented me with a TypeScript error when trying to define providedIn in my providers. The argument type {providedIn: "root"} cannot be assigned to the parameter type {providedIn: Type | "root" | null} & ...

Vue does not recognize the Nuxt $route

Greetings, I've encountered a strange issue. I'm working on a Nuxt app with Typescript. In the created hook, I am using console.log to log this.$route. The log is functioning correctly and I am able to read the params from the route. However, d ...

Union types can be used to constrain generic type parameters in Typescript

I'm working on a function uniqueIds(first: any[], second: any[]): number[] { let prop = first[0] instanceof Owner ? "OwnerId" : "BankId"; return _.unique( _.map( first, o => ...

The Vue router fails to load when using create-vue@3

I've been experimenting with the Vue Router, but it's not giving me the expected outcome. While following the tutorial on https://router.vuejs.org/guide/, I found that if I use the CDN and place it in a standalone HTML file, it works fine. Howev ...

The Angular AOT compilation process is causing essential code to be stripped away from the openlayers

We have recently updated our project to use Angular 7 along with openlayers 5.3, and so far everything has been running smoothly. In an effort to improve initial loading times, we implemented several optimizations during the build process, including enabli ...

Angular 2 Ahead-of-Time compiler: all clear on the error front, yet a nagging feeling of

I've spent the last 72 hours trying to figure out how to make Ahead-of-Time compilation work for my Angular 2 rc.6 application. Currently, my application runs smoothly using Just-in-Time compilation. I've made sure to install all necessary depe ...

Angular 6 CSS spacing dilemmas

We recently made the switch from Angular 5 to Angular 6 and noticed that there is no spacing between the buttons/icons, etc. We are looking to bring back the spaces between the buttons and icons. I have recreated the issue below. As you can see in the Ang ...