3

I am filtering this list

[
 {
 appLearningItemId: 67
 catalogues: (2) [ {id: 1041, value: "New Catalog"},
                   {id: 1058, value: "Test"}]
 categories: (3) [{id: 1, value: "Soft Skills"},
                  {id: 3, value: "Non-technical"},
                  {id: 5, value: "Induction"}]
 code: "CCE0013"
 suppliers: (3) [{id: 1, value: "Company XYZ Ltd"},
                 {id: 2, value: "test c2"},
                 {id: 17, value: "new company"} ]
 title: "07 Values & Beliefs"
 type: {id: 11377, value: "Elearning"}
 }, ... * 682 items
]

with this object and filter

const filters = {
        type: 'Elearning',
        catalog: 1041,
        category: 1,
        supplier: 1
      }
      let advancedFilteredLearningItems = this.originalLearningItems.filter(obj => obj.type.value == filters.type 
       && obj.catalogues.some( catalogs => catalogs.id == filters.catalog)
       && obj.categories.some( category => category.id == filters.category)
       && obj.suppliers.some(supplier => supplier.id === filters.supplier));
       console.log(advancedFilteredLearningItems)

which works great. Sometimes the filter object will have a null value in some or up to 3 of the values eg:

const filters = {
            type: 'Elearning',
            catalog: null,
            category: 1,
            supplier: null
          }

how do I edit the filter code to not filter on null items so in this case I get back all E-learning items with a category of 1? Currently the filter code is looking for null values but I just want to omit it from the filter completely.

1 Answer 1

1

Would adding a null check to all of your filters work? So if it is null you return true because you want all of the catalogs before it? This isn't the most efficient solution, but it should get you to where you need.

const filters = {
    type: 'Elearning',
    catalog: 1041,
    category: null,
    supplier: null
}
let advancedFilteredLearningItems = this.originalLearningItems.filter(obj => 
   (filters.type != null ? obj.type.value == filters.type : true)
   && obj.catalogues.some(catalogs => filters.catalog != null ? catalogs.id == filters.catalog : true)
   && obj.categories.some(category => filters.category != null ? category.id == filters.category : true)
   && obj.suppliers.some(supplier => filters.supplier != null ? supplier.id === filters.supplier : true));
console.log(advancedFilteredLearningItems)

EDIT: A more efficient solution is to not loop through your catalogues if there is no filter. This can be done by adding an extra function

let advancedFilteredLearningItems = this.originalLearningItems.filter(obj => 
   (filters.type != null ? obj.type.value == filters.type : true)
   && this.filterItems(filters.catalog, obj.catalogs)
   && this.filterItems(filters.categories, obj.categories)
   && this.filterItems(filters.supplier , obj.suppliers)
console.log(advancedFilteredLearningItems)

// new function
filterItems(filter, array) {
    if (filter == null) {
        return true;
    }
    return array.some(item => item.id == filter);
}

EDIT 2: In case you don't want to add a new function, this should be as efficient as my first edit

let advancedFilteredLearningItems = this.originalLearningItems.filter(obj => 
      (filters.type       == null || obj.type.value == filters.type)
   && (filters.catalog    == null || obj.catalogues.some(catalogs => catalogs.id == filters.catalog))
   && (filters.categories == null || obj.categories.some(category => category.id == filters.category))
   && (filters.supplier   == null || obj.suppliers.some(supplier => supplier.id == filters.supplier))
);
Sign up to request clarification or add additional context in comments.

6 Comments

If the first one didn't work, then I don't think the second one is going to work... I will keep looking into it
@Bwizard I updated my code. I needed some return values in my function
Works perfectly, thank you v.much. If I could double upVote I would!
You can replace the ternary operators with ORs (filters.type === null || obj.type.value == filters.type)
@pilchard that is a good point. I updated my second edit to reflect that
|

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.