Udders
Udders

Reputation: 6976

Sorting models in a backbone collection strange behaviour

In backbone application I have the ability to sort a collection of models in ascending or descending order based on a couple of attributes, one of which is cost.

The api I am using weirdly returns the cost a string (not sure why I am investing this), but even wierder than this is that I can sort by cost absolutly fine until there is a cost greater than 100000.00 - and I cannot work out why.

Here is the code that does the sorting,

So I set the compartor in the collection,

comparator: function (item1, item2) {

    var val1 = item1.get(this.sort_key);
    var val2 = item2.get(this.sort_key);
    /***added temporarly to sort save project from modal ****/
    if(val2 == undefined){
        val2 = val1;
    }
    /***end added temporarly to sort save project from modal ****/
    if (typeof (val1) === "string" ) {
        val1 = val1.toLowerCase();
        val2 = val2.toString().toLowerCase();
    }

    var sortValue = val1 > val2 ? 1 : -1;
    return sortValue * this.sort_order;

}

and then I run this code within the collection,

this.sort_key = filters.order.by;
    this.sort_order = filters.order.type == "desc" ? -1 : 1;
    // console.log(this.sort_order);
    this.sort();

Lets say I have values of 10000.00, 20000.00, 30000.00, 40000.00 and 200000.00 If order ascending order I get the following returned,

  1. 10000.00
  2. 20000.00
  3. 200000.00
  4. 30000.00
  5. 40000.00

and if I sorting a descening order I get the following return

  1. 40000.00
  2. 30000.00
  3. 200000.00
  4. 20000.00
  5. 10000.00

Why would this be happening I cannot work it out.

Upvotes: 0

Views: 65

Answers (1)

timothyclifford
timothyclifford

Reputation: 6959

It's happening because you're sorting as strings rather than numbers.

Have a play around with JavaScript in your console to see but for example, the following will resolve true:

"10000000.00" < "400000.00"

Update your function to parse values to integers or floats before comparing:

comparator: function (item1, item2) {
    var val1Int, val2Int;
    var sortValue = 0;
    var val1 = item1.get(this.sort_key);
    var val2 = item2.get(this.sort_key);
    /***added temporarly to sort save project from modal ****/
    if(val2 == undefined){
        val2 = val1;
    }
    /***end added temporarly to sort save project from modal ****/
    val1Int = parseInt(val1, 10);
    val2Int = parseInt(val2, 10);
    if (val1Int > val2Int) {
        sortValue = 1;
    }
    else if (val1Int < val2Int) {
        sortValue = -1;
    }
    return sortValue * this.sort_order;
}

Upvotes: 2

Related Questions