0
votes

I am trying to sort my columns of my table using Angular 2

the pipe transform code is

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({  name: 'orderBy' })
export class OrderByPipe implements PipeTransform {

  transform(records: Array<any>, args?: any): any {

    return records.sort(function(a, b){
      if(a[args.property] < b[args.property]){
        return -1 * args.direction;
      }
      else if( a[args.property] > b[args.property]){
        return 1 * args.direction;
      }
      else{
        return 0;
      }
    });
  };
}

I have defined a sort function in component.ts file as following as :

  sort(property){
    this.isDesc = !this.isDesc; //change the direction
    this.column = property;
    this.direction = this.isDesc ? 1 : -1;
    //this.sort(this.column);
  };

HTML looks like this

 <th class="cell-width-header title" (click)="sort(sellerNo)">
            Seller No
            <i class="fa" [ngClass]="{'fa-sort': column != 'sellerNo', 'fa-sort-asc': (column == 'sellerNo' && isDesc), 'fa-sort-desc': (column == 'sellerNo' && !isDesc) }" aria-hidden="true"> </i>
          </th>




 <tr *ngFor="let x of selectedData  | orderBy: {property: column, direction: direction}">


            <td>{{x.sellerNo}}</td>

but after loading the page, I get following error

zone.js:522 Unhandled Promise rejection: Error in ./FundingRequestComponent class FundingRequestComponent - inline template:208:14 caused by: Cannot read property 'sort' of undefined ; Zone: angular ; Task: Promise.then ; Value: ViewWrappedError {__zone_symbol__error: Error: Error in ./FundingRequestComponent class FundingRequestComponent - inline template:208:14 cau……} Error: Error in ./FundingRequestComponent class FundingRequestComponent - inline template:208:14 caused by: Cannot read property 'sort' of undefined at ViewWrappedError.ZoneAwareError (http://localhost:4200/polyfills.bundle.js:6688:33) at ViewWrappedError.BaseError [as constructor] (http://localhost:4200/vendor.bundle.js:94913:16) at ViewWrappedError.WrappedError [as constructor] (http://localhost:4200/vendor.bundle.js:94978:16) at new ViewWrappedError (http://localhost:4200/vendor.bundle.js:96282:16)

1
What is selectedData's type? - Vega
It is JSON, coming from backend service - DP3
what is sellerNo? a variable in your .ts file? If not, I suppose that the name of the property you want so sort by. Wrapp it in '' - Jota.Toledo
And the only place where you are calling .sort in an object is in the pipe. Most likely selectedData is null/undefined when you call the pipe.... - Jota.Toledo
@Jota.Toledo seller no is the name of the column and an element in my json data that I am filtering - DP3

1 Answers

1
votes

I assume you are loading the data (selectedData) for this template asynchronously in the component's class, so at the start it's not yet returned form the service, hence selectedData = undefined.

There are several things you can do to mitigate that:

1. Initialize the data in the component

Set the selectedData class property to an empty array so when the pipe runs its input will be an array even if the backend data is not yet returned.

export class MyComponent {
    selectedData = [];
}

2. Prevent evaluation of this part of the template with *ngIf

Don't render the template part with said pipe until you have the array.

<table *ngIf="selectedData">
  <!-- ... -->
  <tr *ngFor="let x of selectedData  | orderBy: {property: column, direction: direction}">
</table>

3. Make the pipe "empty-input-safe" by providing a default input

This should be the preferred solution because with that you won't have to remember to employ any special logic (like ver. 1 or ver. 2) each time you're using this pipe somewhere.

@Pipe({  name: 'orderBy' })
export class OrderByPipe implements PipeTransform {
  transform(records: Array<any> = [], args?: any): any {
    /* ... */

See the records = [] default in the transform's method parameter?

I try to use this as a general rule of thumb to always prepare the pipe for getting no input initially. Makes a lot of headaches go away :)