Conditionally apply filters with ng-repeat

20,012

Solution 1

Here is the requested alternate version of the answer from @callmekatootie using ng-if (v1.1.5):

<table>
    <tr ng-repeat="(metric, metricData) in data">
        <td>{{metric}}</td>
        <td ng-if="isNumber(metricData)">{{metricData | number}}</td>
        <td ng-if="!isNumber(metricData)">{{metricData}}</td>
    </tr>
</table>

This has the advantage of only running the filter on the elements which are numeric. This is probably of little benefit in this case but may be useful in other more complex filter situations. To answer your other question about the built-in angular.isNumber, @callmekatootie does use that in the scope function isNumber, which is only a wrapper for using the built-in in the view.

Here is a fiddle

Solution 2

I know this is old, but I think the best solution is to move the logic to a filter.

app.filter("metricDataFilter", function($filter) {
    return function(value) {
      if(angular.isNumber(value)) {
          return $filter("number", value);  
      }

      return value;
    }  
}

That way the HTML is more concise, and angular won't have to redraw dom elements

<table>
    <tr ng-repeat="(metric, metricData) in data">
        <td>{{metric}}</td>
        <td>{{metricData | metricDataFilter}}</td>
    </tr>
</table>

Solution 3

You could try it this way - In your controller, you can have a function which identifies if the provided value is a string or a number:

$scope.isNumber = function (value) {
    return angular.isNumber(value);
};

Next, in your view you could have the following:

<table>
    <tr ng-repeat="(metric, metricData) in data">
        <td>{{metric}}</td>
        <td ng-show="isNumber(metricData)">{{metricData | number}}</td>
        <td ng-hide="isNumber(metricData)">{{metricData}}</td>
    </tr>
</table>

Thus, when the metricData is a number, it is filtered and when it is a string, it is output as it is.

Share:
20,012
EnigmaRM
Author by

EnigmaRM

I've focused my learning to front-end technologies. AngularJS, D3.js, jQuery, and AJAX.

Updated on April 06, 2020

Comments

  • EnigmaRM
    EnigmaRM about 4 years

    I have an object that contains a mixture of numbers and text for values. I'd like to apply the numbers filter to the object's value when it's a number (obviously). But when it isn't a number, I'd be okay with it just spitting out the string. As is, applying | number to the value formats the numbers, but leaves the string values empty (afterall, they aren't numbers).

    I'm guessing it'll have to be a custom filter (which I have yet had a need to make). Is there a way to do it solely within the HTML when doing the ng-repeat?

    <table>
          <tr ng-repeat="(metric, metricData) in data">
            <td>{{metric}}</td>
            <td>{{metricData | number}}</td>
          </tr>
    </table>
    
    $scope.data = { name:"this is the name", 
                    score:48
                    outcome:"as expected",
                    attendance:820,
                    total:212.34
                  };
    
    • callmekatootie
      callmekatootie almost 11 years
      Just so you know, customer filter is not a bad way of doing it...
    • EnigmaRM
      EnigmaRM almost 11 years
      I imagine it is not. I just haven't learned how to do it yet. Maybe it's time I learn. ha.
  • Dan
    Dan almost 11 years
    +1 A variation could use ng-if (v. 1.1.5+) so the data set isn't filtered at all in the off case (this may save time with large data sets / complex filters).
  • EnigmaRM
    EnigmaRM almost 11 years
    I like this solution. Doesn't angular have a built-in isNumber directive? angular.isNumber? I tried using that for something else, but couldn't get it to work in the HTML.
  • EnigmaRM
    EnigmaRM almost 11 years
    @sh0ber what is the proper syntax for using ng-if? I just upgraded my angular version to 1.1.5. But I don't find any documentation about the use of that directive. Just been told "use it like ng-switch"... Would you be willing to submit a solution using nf-if? Thanks.
  • callmekatootie
    callmekatootie almost 11 years
    I think also OP wanted to know if in built function angular.isNumber() can be used directly inside the HTML code, which I do not think is possible. Correct?
  • Dan
    Dan almost 11 years
    @callmekatootie I think so, expressions seem to only support variables on a scope.
  • Jason
    Jason over 10 years
    I think show/hide on a <td> could cause issues...better use ng-if / ui-if