haydnD
haydnD

Reputation: 2293

how do I display a list in a custom sort order with angular?

I'm trying to display a list of objects on screen with custom order [m,r,d,v,o]. I've tried using the sort() function which works for the first and last items but the middle comes through randomly.

Should I be using the sort() function for this situation? If so what am I doing wrong?

In the UI I'm using a *ngFor to loop through array.

<div *ngFor="let stuff of sortedStuff; let i = index;">
    <div>want to display in the custom sort order here</div>
    <ul><li> {{ stuff.someproperty }} <li></ul>
</div>

Code that builds the array:

var sortedStuff = stuff.splice(0);
sortedStuff.sort((obj1) => {
    if (obj1.propertyX === 'M') {
        return -1;
    }

    if (obj1.propertyX!= 'M' && obj1.propertyX!= 'D' && obj1.productType != 'V' && obj1.propertyX!= 'O' && obj1.propertyX=== 'R'){
        return 1;
    }

    if (obj1.propertyX!= 'M' && obj1.propertyX!= 'R' && obj1.propertyX!= 'V' && obj1.propertyX!= 'O' && obj1.propertyX === 'D'){
        return 1;
    }

    if (obj1.propertyX!= 'M' && obj1.propertyX!= 'D' && obj1.propertyX!= 'R' && obj1.propertyX!= 'O' && obj1.propertyX === 'V'){
        return 1;
    } 

    if (obj1.obj1.propertyX != 'M' && obj1.obj1.propertyX != 'D' && obj1.obj1.propertyX != 'V' && obj1.obj1.propertyX != 'R' && obj1.obj1.propertyX === 'O'){
        return 1;
    }
    return 0;
});

Upvotes: 0

Views: 1621

Answers (2)

psamwel
psamwel

Reputation: 1062

No, you should not use sort(). A simple solution would be to just write a custom function like:

  csorts(items: string[], order: string[]) {
    let returnItems: string[] = [];
    for (let ord of order) {
      let ordered = [];
      for (let item of items) {
        if (item === ord) {
          ordered.push(item);
        }
      }
      returnItems = returnItems.concat(ordered);
    }
    return returnItems;
  }

resulting in use of:

let items = ['m','r','d','m','v','r','m','d','d','r']
let order = ['m','r','d','v','o']
let ordered = csort(items, order);
console.log(ordered);

...

[ 'm', 'm', 'm', 'r', 'r', 'r', 'd', 'd', 'd', 'v' ]

Upvotes: 0

Lazar Ljubenović
Lazar Ljubenović

Reputation: 19764

Nothing wrong with Angular here, you're using the built-in Array#sort function wrongly.

The lambda you pass ino sort is a "compare function" with the following properties (from the linked MDN):

If compareFunction is supplied, the array elements are sorted according to the return value of the compare function. If a and b are two elements being compared, then:

  • If compareFunction(a, b) is less than 0, sort a to an index lower than b, i.e. a comes first.
  • If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAscript standard does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
  • If compareFunction(a, b) is greater than 0, sort b to a lower index than a. compareFunction(a, b) must always return the same value when given a specific pair of elements a and b as its two arguments. If inconsistent results are returned then the sort order is undefined.

The funtion in your code is working only with one argument, which means there is no way to properly compare the two items from the array.


If this is not an approach you like, I can recommand using sortBy from loash. It accepts a function which "grabs" some data from an object. The grabbed data is standardy compared as is.

Upvotes: 2

Related Questions