0

I need to have actual sorted $scope.array by updated_at (linux timestamp, newest elements at the beginning of the array). How i can do this? $scope.array sometimes may have changes, and i need always keep this array in sorted state.

$scope.array = [{updated_at: 1438405112}, {updated_at: 1438405110}, {updated_at: 1438405102}];

$scope.array2 = [{updated_at: 1438105112}, {updated_at: 1438205110}, {updated_at: 1438405104}];

$scope.array = $scope.array.concat($scope.array2);      


$scope.$watch('array', function(newValue) { 
 $scope.array = $filter('orderBy')($scope.array, 'updated_at'); 
}, true);
  • 1
    You posted code, but failed to tell us what the problem was with the code. Why do you force us to guess? Why do you use a watch, rather than sorting the array every time it is modified? Why not use the orderBy filter in the view? – JB Nizet Aug 01 '15 at 12:30
  • Sorry, i have no idea that i should use. I just need keep array in sorted state :) "$scope.$watch" and filter not sorting my array. filter in the view i can't use, cause it sort array only in html, and indexing does not match with $scope. – lemmik1221 Aug 01 '15 at 12:34
  • Open your browser console. Read the error messages. Try to figure them out. If you're stuck, post them. Post a complete minimal reproducible example in a plunker. And tell us **why** you would need to keep your array in sorted state. – JB Nizet Aug 01 '15 at 12:36

1 Answers1

0

Your code generally looks fine to me, the only thing I see that might cause issues is the line

$scope.array = $filter('orderBy')($scope.array, 'updated_at'); 

This line potentially generates a new array each time and assigns it to the scope. As a result the $watch function gets fired again since the value "changed"..

What you want is a sort that does not create a new array but changes the existing array.

Here is my plunker that does what you want

http://plnkr.co/edit/TP5mzA40m77lS5gCbRfT?p=preview

angular.module('myApp').controller('MyCtrl', function($scope){

  $scope.awesomeThings = ['c','b','a'];

  $scope.add = function(str){
    $scope.awesomeThings.push(str);
  }

  $scope.$watch('awesomeThings', function(){
    $scope.awesomeThings.sort();
  }, true);

});

As you can see I am using .sort() function on array and I do not assign it back on the scope.

I must state that this is a bit expensive. you might want to simply write a new data structure called "sorted list" which simply does CRUD in a sorted fashion.

here is a solution I found online: https://github.com/shinout/SortedList

How to sort object by timestamp

This is how you can use .sort in order to sort objects by timestamp

http://plnkr.co/edit/IHpK6jv8izzDMEffUz9x?p=preview

var $scope = {};
$scope.array = [{updated_at: 1438405112}, {updated_at: 1438405110}, {updated_at: 1438405102}];
$scope.array2 = [{updated_at: 1438105112}, {updated_at: 1438205110}, {updated_at: 1438405104}];
$scope.array = $scope.array.concat($scope.array2);     


var ASC = 1;
var DESC = -1;

var sortOrder = ASC;

$scope.array.sort(function(a,b){
  return sortOrder * ( a.updated_at - b.updated_at );

});

console.log($scope.array);
document.write('<pre>' + JSON.stringify($scope.array,{},4) + '</pre>');
guy mograbi
  • 27,391
  • 16
  • 83
  • 122
  • Thank you, but i need sort objects array by newest timestamp and sort() not helps me ( – lemmik1221 Aug 01 '15 at 18:12
  • you can pass a function to sort and specify how you want it to sort. see examples at: http://www.w3schools.com/jsref/jsref_sort.asp – guy mograbi Aug 02 '15 at 04:57
  • @lemmik1221 - I added another snippet for sorting however i feel as if it should be in a different question such as : http://stackoverflow.com/questions/8175093/simple-function-to-sort-an-array-of-objects – guy mograbi Aug 02 '15 at 05:05