0

I have the following code that works fine as far as sorting by the desired property:

<select ng-model="sortorder">
   <option value="name">Sort by Name</option>
   <option value="created">Sort by Date</option>
</select>

<div ng-repeat="item in items | orderBy:sortorder">
    {{item.name}}, {{item.created}}
</div>

However, the date comes in as a string, ex: April, 5 2016 which is not giving me accurate sorting. How can I detect if the list is being sorted by created and then convert that to a Date object to get accurate results.

Sample output:
sample name 1, April 6, 2016
sample name 2, January 13, 2014

farjam
  • 2,146
  • 6
  • 31
  • 66
  • Don't you have a raw representation of the date for each object? Can you return the raw date from the server? – Alon Eitan Apr 27 '16 at 20:12
  • Possible duplicate of [Sort Javascript Object Array By Date](http://stackoverflow.com/questions/10123953/sort-javascript-object-array-by-date) – Aditya Singh Apr 27 '16 at 20:23

1 Answers1

1

You have to turn the date into a timestamp (i.e. number of seconds since...) in order to sort them accurately. Be careful with timezones, as javascript dates are subject to the user's computer/browser settings. I recommend looking at MomentJS to handle your date operations.

You wouldn't detect if the user is choosing the formatted date to sort. Instead, you would add an additional element to each data row that stores the timestamp version of the date. You can do that in your controller.

claywhipkey
  • 833
  • 7
  • 13
  • 1
    Also, javascript date parsing is very volatile across browsers, and the only string format that is fully-supported to be parsed into a date object is ISO 8601 `YYYY-MM-DDT00:00:00`. You can cut the time off and it is still compliant. If you can get your backend to return the date like this it will help you a lot. – claywhipkey Apr 27 '16 at 20:19
  • Thanks. I got my backend to give me the raw date (timestamp) and it's now sorting fine. Is it possible I can instruct it to sort the names ascendingly but sort the timestamp descendingly? – farjam Apr 27 '16 at 20:27
  • Yes, angular's orderBy takes two arguments. The first is the key to sort on, the second is the direction. At this point, your use case might be getting too complex for the ng-model approach. You might need to create a scope function, triggered by ng-change or ng-click, that sets a couple scope variables (sortColumn and sortDirection). – claywhipkey Apr 27 '16 at 20:32
  • Or you could add a $watch function to your controller that watches `sortorder` and changes a direction scope variable if the new value is the date. – claywhipkey Apr 27 '16 at 20:36
  • Thanks, I'm getting closer. I added a watch function and now I'm able to catch the value of the select element. How can I change the direction of the orderBy in my controller? – farjam Apr 27 '16 at 20:50
  • Create a scope variable for the direction. This should be a boolean. `true` will reverse the normal direction of your array. See https://docs.angularjs.org/api/ng/filter/orderBy you use it in the template like `orderBy:sortorder:direction` – claywhipkey Apr 27 '16 at 20:53