1

I am writing an angular.js application, and i need to do a filter-orderBy on a JSON array. if i do it by creating a method that takes no parameters and refers to the explicit array with $scope, everything works fine:

...
<th class="ui th" ng-click="sortArray('name')">Name</th>
...

sortArray = (sortParam) ->
  $scope.myArray = $filter('orderBy')($scope.myArray, sortParam)

but if i try to generify it by having the array as a method parameter, like this:

...
<th class="ui th" ng-click="sortArray(myArray,'name')">Name</th>
...

sortArray = (arr,sortParam) ->
  arr = $filter('orderBy')(arr, sortParam)

it seems like the array is sorted in the backend, but the table that uses it for ng-repeat stays unchanged, visually. example: i have this array:

{ arr : 
 [
  { 'id' : 1 },
  { 'id' : 2 },
  { 'id' : 3 }
 ]
}

now, in the first case, if i sort with the first case, the rendering changes to match the sorted array. but in the second case, the rendering will not change (it will still show as 1 - 2 - 3), but if i have it print the id of the first cell (which renders '1') it will say '3' (the top of the array after sorting. hope it makes sense.

the reason i need it is to open a modal with the content of the row clicked. for that, i put an ng-click in the ng-repeat tag, with the index:

<tr ng-repeat="row in arr | filter:filter" ng-click="loadModal($index)">

that way, even if the array is reordered, the value of loadModal($index) does not change, in will open with the correct row.

so, after this long explanation - how do i write a generic method that can take and order different array (code reuse) but affects the rendering too? or, is this the right way to even do so? i don't have an ID for the entries of the array, and there is nothing natural i can cling to, to identify the row.

1 Answer 1

1

I think you don't need to write a generic method!

Use the orderBy filter with ng-repeat in your view like

<tr ng-repeat="friend in friends | orderBy:predicate:reverse">

And on ng-click set the predicate value like

<th class="ui th" ng-click="predicate = 'name'; reverse= !reverse">Name</th>

When you click Name the predicate will pass the value to orderBy filter and your view adjust the latest change automatically, reverse= !reverse used for toggle your sort.

Check the angularjs Demo

Sign up to request clarification or add additional context in comments.

4 Comments

you are right at that, and i forgot some more info: the problem with the solution in the demo (which i did try before) is this: when the user click on an entry in the table, i open a modal with the content of that row. the way i found to correlate between the table and the backend array is to put an ng-click="openModal($index)" in the ng-repeat tag, so the initial rendering sets the value of ng-click for each row, which does not change when i reorder the array. i edited the question above.
openModal($index) this is not gonna help you ! instead $index use your array unique property something like Id because $index used for ng-repeat item indexing.
it is true and that is the reason i use it, as $index might change with reorder but openModal(($index) will be created once on page load, will correspond to the array's initial indexes and will not change on reorder.
I think there is some misunderstanding ! Initially when you click row two $index return 1, after reordering if you click again on row two $index will return 1 but the content of the row changed. In your case always $index will be same but the content of the row will be changed. So if you want to get row content use some unique id from your array instead $index

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.