1

I am trying to enable filtering within React on an array of JSON. I am sorting alphabetically, then I need to filter by category key IF the select dropdown is changed to that category (this is passed via the filter argument on the onChange event).

Then I map over the filtered array, outputting the relevant HTML.

My problem is, how do I essentially skip the filter, if the 'All' option is selected in the select dropdown? Currently when that is selected, no elements are passed to map and nothing is rendered out.

Thanks :)

renderProduce(orderBy, filter) {
    return this.fetchProduce()
        .sort(function(a,b) {
            return (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0);
        })
        .filter(function(item) {
            if ( filter != 'All' ) {
                return item.category == filter;
            }
        })
        .map((item, i) => (
            <Item key={i} item={item} />
        ));
}

3 Answers 3

2

You can do that by making the filter callback always return true if the 'All' filter is selected.

    .filter(function(item) {
        return filter === 'All' || item.category == filter
    })
Sign up to request clarification or add additional context in comments.

4 Comments

I know this is an early stage in our relationship - we just met - but I love you.
Some do it for the rep, I do it for the love. ;)
but this calls the filter-function on every item of the list, instead of simply not filtering.
@Thomas That's right. Are you hinting at the fact that it might be slower compared to not filtering? It probably is, but it is also fast enough, while (arguably) clearer than breaking the chain and inserting an if around the filter.
1

Array#filter produces a new array populated with all elements for which the corresponding iteration of the filter callback returned true. Currently what your filter operation returns when 'All' is selected is undefined, which is falsey. Return true after your if condition within the filter callback:

.filter(function(item) {
    if ( filter != 'All' ) {
        return item.category == filter;
    }
    return true;
})

Comments

0

if filter === 'All', simply don't filter

2nd: unless you filter by index, filtering should always be the first step. Because the rest can now be executed on a potentially smaller set of data.

renderProduce(orderBy, filter) {
    var arr = this.fetchProduce();
    return (filter === "All"? arr: arr.filter(item => item.category == filter))
        .sort((a,b) => a.name.localeCompare(b.name))
        .map((item, i) => (
            <Item key={i} item={item} />
        ))
}

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.