This will sound as an easy problem but I spent my Sunday trying to figure out what's wrong with my implementation described below so I am posting it to SO as a last resort.
I have a javascript application that receives data structures from a server. The server side sends the data unsorted for performance reasons.
Here is a snippet of the the javascript code receiving data:
var seriesRawDataArray = ko.observableArray();
...
analyticscontext.series(seriesRawDataArray).done(function () {
renderSeries();
});
The analyticscontext
module queries the data using ajax:
function series(seriesData) {
return $.ajax({
url: "/api/analytics/series",
type: "GET",
success: function (data) {
return seriesData(data);
}
});
}
The renderSeries
performs a sort on the data before rendering it:
// Sort the data by date using moment.js
seriesRawDataArray.sort(function (left, right) {
var leftDate = moment.utc(left.timeStamp);
var rightDate = moment.utc(right.timeStamp);
var diff = leftDate.diff(rightDate);
return diff > 0;
});
PROBLEM
Here is a data sample I receive from my server:
Notice the unsorted items at the end.
the seriesRawDataArray.sort
seem to have no effect on the original array which does not get sorted no matter what I change in the sorting method. The output is always:
Notice the unsorted elements here. The libraries I am using and the data is definitely not the problem as this jsfiddle works just fine! Is there something wrong with this code?
short answer
You should return the difference between the two dates, not a boolean:
why
Array.prototype.sort
expects a negative, zero, or positive value to be returned. Generally, you'll write a sort function like this:The anonymous function passed to sort serves as the comparator for the native implementation of the sort function.
However, your negative value doesn't have to be
-1
and your positive value doesn't have to be+1
. Therefore, when sorting numbers, you can instead use the shortcut:In JavaScript, subtracting two dates coerces them both into numbers, which is why we could use
return moment.utc(left.timeStamp).diff(moment.utc(right.timeStamp))
(instead of direct subtraction
-
, this method usesmoment.prototype.diff
from themoment.js
library)However, in your code, you returned
diff > 0
, which can be eithertrue
orfalse
. Because of type coercion, JavScript will readtrue
as1
andfalse
as0
. This means your sort function will never return-1
. Therefore, your elements will not be sorted correctly.Since moment can format valid dates the best way is to use the sort method javascript so when formatting the date to timestamp, basically you sort by number.
References: momentjs.com/docs/#/displaying/format , w3schools.com/jsref/jsref_sort.asp