0

I have a list of films that I want to sort by a choice from a dropdown list. I'm using a custom function to do the sorting to exclude non-numeric options. It works fine when passing the function directly but I'm not sure how to pass that function as a value in the dropdown.

    <select name="sort" id="" ng-model="filters">
        <option value="sortByRtRating">Rotten Tomatoes rating</option>
        <option value="sortByImdbRating">IMDB rating</option>
    </select>

<div ng-repeat="movie in movieList | toArray | orderBy:filters.sort:true">

$scope.sortByRtRating = function(item) {
  if (!item.details) return -1;
  if (typeof item.details.rt.rating != 'number')
    return -1;
  return item.details.rt.rating;
}  

$scope.sortByImdbRating = function(item) {
  if (!item.details) return -1;
  if (typeof item.details.imdb.rating != 'number')
    return -1;
  return item.details.imdb.rating;
} 
0

1 Answer 1

1

There are 2 ways to solve this - depending on how you implement the select - and thus what the select's ng-model will hold.

#1 - with function names as the ng-model of select

When you create a select with normal <options> - i.e. without ng-options (as you did) - the ng-model can only hold the function name as a string - which is a value of the <option>.

<select ng-model="filterFnName">
  <option value="sortByRtRating">Rotten Tomatoes rating</option>
  <option value="sortByImdbRating">IMDB rating</option>
</select>

Then you need to $eval to get the function out of the function name (the functions need to be exposed on the scope):

<div ng-repeat="movie in movieList | orderBy:$eval(filterFnName):true">{{movie}}</div>

#2 - with function as the ng-model of select

This is only possible with ng-options as Angular can bind to a complex object (including functions).

You can define the following in your controller:

$scope.filterFns = [
    {l: "Rotten Tomatoes rating", fn: sortByRtRating}, 
    {l: "IMDB rating", fn: sortByImdbRating}
];
$scope.filterFn = sortByRtRating;

function sortByRtRating(item){...}

function sortByImdbRating(item){...}

And you can select and use the actual function object:

<select ng-model="filterFn" ng-options="f.fn as f.l for f in filterFns">
</select>

<div ng-repeat="movie in movieList | orderBy:filterFn:true">{{movie}}</div>

plunker

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

Comments

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.