Search code examples
angulartypescriptngx-datatable

angular 5 ngx datatable sorting not working


I am using [ngx-datatable] to show some data from database. So for that I have made my component(here I am using hotel as component). All the hotels are showing fine in datatable but the sorting for hotelname is not working at all. When I am doing click on the hotelname heading it is showing the table as blank.

I have taken example from here

So for now hotel.component.ts looks like this

    import { Component, OnInit } from '@angular/core';
    import { HotelService } from '../hotel.service';
    import { HttpClient } from '@angular/common/http';
    import { Hotel } from './hotel';
    import { Router} from '@angular/router';
    import { ViewEncapsulation } from '@angular/core';


@Component({
  selector: 'app-hotel',
  templateUrl: './hotel.component.html',
  styleUrls: ['./hotel.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class HotelComponent implements OnInit {

  hotels: Hotel[] = [];
  loading: boolean = false;
  rows = [];

  columns = [
    { name: 'hotelname', sortable: true },
    { name: 'Action', sortable: false },
  ];

  constructor( 
    public hotelService: HotelService,
    private router: Router
  ) { }

  ngOnInit() {
    this.getAll();
  }

  getAll() {
    this.hotelService.getHotels().subscribe(res => {
      this.rows = res as Hotel[];
    }, err => {
      console.log(err);
    });
  }


  onSort(event) {
    // event was triggered, start sort sequence
    this.loading = true;
    setTimeout(() => {
      const rows = [this.rows];
      console.log(rows);
      // this is only for demo purposes, normally
      // your server would return the result for
      // you and you would just set the rows prop
      const sort = event.sorts[0];
      rows.sort((a, b) => {
        return a[sort.prop].localeCompare(b[sort.prop]) * (sort.dir === 'desc' ? -1 : 1);
      });

      this.rows = rows;
      this.loading = false;
    }, 1000);
  }

}

hotel.component.html looks like this

<div class="main-content">
  <div class="container-fluid">
    <div class="row">
      <div>
        <ngx-datatable
          class="material striped"
          [rows]="rows"
          [columns]="columns"
          [columnMode]="'force'"
          [headerHeight]="40"
          [footerHeight]="50"
          [rowHeight]="'auto'"
          [externalSorting]="true"
          [loadingIndicator]="loading"
          (sort)="onSort($event)">
        </ngx-datatable>
      </div> 
    </div>
  </div>
</div>

and hotel.service.ts looks like this

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { Observable } from 'rxjs';
import { HttpClientModule } from '@angular/common/http';
import { HttpClient } from "@angular/common/http";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';

const domain = 'http://localhost:8080';

@Injectable()
export class HotelService {

  headers = new Headers({ 'Content-Type': 'application/json' });

  constructor(private http: Http) { }

  getHotels(){
    return this.http.get( domain + '/api/hotel', {headers: this.headers}).map(res => res.json() );
  }

}

Solution

  • const rows = [this.rows]; will generate an array of array which upon setting to this.rows will result in a empty grid. Change that line to

    const rows = [...this.rows];
    

    This copies every element of this.rows to new array rows and can be sorted