2
\$\begingroup\$

I have a web component that is rendering a list of items and I have this method for filtering these items based in a filterBy object that is being updated by other events and stored in the same component class.

filterBy = {
    comment: '', // string
    rating: [] // array of numbers
}

filterFeedback(items) {
    let filteredItems = [];
    const pagination = { offset: 0, limit: 10, totalCount: items.length };
    const { comment, rating } = this.filterBy;

    const filteringFn = (condition) => {
        items.map((item) => {
            if (filteredItems.length < pagination.limit) {
                if (condition(item)) {
                    filteredItems.push(item);
                }
            } else {
                return;
            }
        });
    }
    if (comment && (!rating || rating.length === 0) && comment !== '') {
        filteringFn((item) => item.comment && item.comment.includes(comment));
    } else if (!comment && rating && rating.length > 0) {
        filteringFn((item) => rating.some((value) => value === item.rating));
    } else if ((comment && comment !== '' )&& rating && rating.length > 0) {
        filteringFn((item) => item.comment && item.comment.includes(comment) && rating.some((value) => value === item.rating));
    } else {
        filteredItems = items ? items.filter((item, i) => i < pagination.limit) : [];
    }

    return filteredItems;
}

I was analyzing this code and trying to make it more clear and readable. I think the filteringFn saves me a lot of code duplication but still, I found the conditionals unreadable. Besides, it's not scalable in case I'd like to add more filters.

\$\endgroup\$
1
  • \$\begingroup\$ The current question title, which states your concerns about the code, applies to too many questions on this site to be useful. The site standard is for the title to simply state the task accomplished by the code. Please see How to Ask for examples, and revise the title accordingly. \$\endgroup\$ Mar 5, 2019 at 19:50

1 Answer 1

2
\$\begingroup\$

If one of your filters is undefined, just set it to always succeed.

If one of your parameters is undefined, set it to something so that you don't have to check it over and over.

Truncate output to pagesize at the end.

filterFeedback(items) {
    const pagination = { offset: 0, limit: 10, totalCount: items.length };
    const filtRatings=new Set( 
        ( this.filterBy.rating && this.filterBy.rating.length ) ?
          this.filterBy.rating : items.map( item => item.rating ) 
    );
    const filtComment=this.filterBy.comment || '';

    return items.filter( item => 
        ( item.comment || '' ).includes(filtComment) 
        && 
        filtRatings.has(item.rating) 
    )
    .slice(0,pagination.limit);

}
\$\endgroup\$
1
  • \$\begingroup\$ Hi, I appreciate your answer. I think it reduces a lot the lines of code while it's getting the same approach, but I found your solution more difficult to read, no offense. Still, you gave me a good idea on getting rid of the verification of undefined parameters from the beginning and set the filters later. \$\endgroup\$
    – Juan Rivas
    Mar 8, 2019 at 16:52

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.