1

I'm attempting to write a filter for use in a grid that will catch all null, undefined, blank string, or other similar values and display a dash "-". I've written the following so far, but it doesn't catch null values, and I'm wondering if it could be more succinct and possibly refactored to avoid three layers of nested if/else statements. Percentage values need to be checked that they're over 0 and under 1. Also, negative numbers and 0's should be returned as is. Thanks!

angular.module('AdverseEventsExplorer.main').filter('emptyCellFilter', function ($filter) {
    return function (input, cellFilter, args1, args2) {    

        if (cellFilter == undefined) {
            return (angular.isNumber(input) || angular.isDefined(input) && input.length > 0) ? input : '-';
        } else {
            if (cellFilter.match(/pctg|percent|pctgFilter|incidence/ig)) {
                return (input > 0 && input < 1.0000000) ? $filter(cellFilter)(input, args1, args2) : '-';
            } else {
                return (angular.isNumber(input) || angular.isDefined(input) && input.length > 0) ? input : '-';
            }
        }

    };
});

Version 2.0 taking into account @tymeJV's comment:

angular.module('AdverseEventsExplorer.main').filter('emptyCellFilter', function ($filter) {
    return function (input, cellFilter, args1, args2) {

        if (!cellFilter) {
            return (angular.isNumber(input) || (input)) ? input : '-';
        } else {
            if (cellFilter.match(/pctg|percent|pctgFilter|incidence/ig)) {
                return (input > 0 && input < 1.0000000) ? $filter(cellFilter)(input, args1, args2) : '-';
            } else {
                return (angular.isNumber(input) || (input)) ? $filter(cellFilter)(input, args1, args2) : '-';
            }
        }

    };
});
1
  • 1
    null, undefined, 0, "" - all falsy values can just do a if (value) check. Commented May 7, 2015 at 17:04

2 Answers 2

3

Whenever you encounter a function that's getting too complex to refactor try extracting some of the smaller statements to concisely named variables. It makes it much easier for our brains to keep track of the function's requirements, and it's also more readable to new devs reading your code.

var inputHasValue = angular.isNumber(input) || input;
if(!inputHasValue){
    return '-';
}
if (!cellFilter) {
    return input;
}

var isPercentageCell = cellFilter.match(/pctg|percent|pctgFilter|incidence/ig);
var valueIsInRange = input > 0 && input < 1;
if(!isPercentageCell || valueIsInRange){
    return $filter(cellFilter)(input, args1, args2);
}
return '-';
Sign up to request clarification or add additional context in comments.

7 Comments

awesome, thanks @hankscorpio. now i have a few columns that i'd like to be able to display 0 and negative values, what do you think is the best way to catch those scenarios? seems like i may need to explicitly handle those or use a different cellFilter.
When you say you want to "display" those values, what do you mean? Display them as-is (i.e. return input;) or return them filtered by cellFilter? You could make a distinction in this function between valueIsInRange and valueIsInPercentRange. Hard to say really without knowing what you want to do with it.
What determines whether or not you want to display "0 and negative values" in some cells and not others?
display them as is (return input), and at this point, it's really arbitrary what determines which columns we want to return 0's and negatives values as is. it's mainly currency columns.
You'd have to make some distinction in your filter arguments (or, as you said, just use a different filter). Maybe that can be done similar to how you're using cellFilter.match()? You can pass in extra colon-separated arguments to filters to do that: <span>{{myData | filterName: 'someArg': 'someOtherArg'}}</span> It might be best to make a different kind of filter for each cell type if you know that beforehand, and then you could simplify the filter functions without worrying about detecting which filter to use.
|
1
typeof x ==='number' || !!x 

is false when x is null, undefined or empty string

Only one case in which it doesn't work – if you need to filter boolean variables, but your case doesn't seem to need it.

Anyway in that case you can use

typeof x === 'boolean' || typeof x ==='number' || !!x

2 Comments

ah nice, so similar to (x), but let's 0 and negative values through?
hm, actually it seems that !!(-1) === true, but !!(0) === false

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.