0

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)

5
  • What is selectedData's type? Commented Jul 23, 2017 at 18:28
  • It is JSON, coming from backend service Commented Jul 23, 2017 at 18:29
  • 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 '' Commented Jul 23, 2017 at 18:31
  • 1
    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.... Commented Jul 23, 2017 at 18:33
  • @Jota.Toledo seller no is the name of the column and an element in my json data that I am filtering Commented Jul 23, 2017 at 18:42

1 Answer 1

1

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 :)

Sign up to request clarification or add additional context in comments.

1 Comment

is there a way i could implement this with 3 columns that i can choose from?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.