Handling Multiple Filter Terms in svelte

Viewed 118

I am trying to handle multiple filter terms in array in svelte But I cant seem to find a way around that!

I have tried switch cases and single filter function !

When i tried this code it worked but after putting + filters at once it tales the last filter and does not consider older filters

The Search store

import { writable } from 'svelte/store';

export const Search = writable({
    brand: '',
    color: '',
    format: '',
    grammage: '',
    nbfeuilles: ''
});

The Product List Component

import { Search } from '../../../../store/Search';

let resSearch = [];
    const searchProducts = (search) => {
        // if (search.brand || search.color || search.grammage || search.format || search.nbfeuilles) {
        resSearch = [];
        if (search.brand) {
            let brandSearch = searched.filter((product) => product.brand == search.brand);
            resSearch = [...resSearch, ...brandSearch];
        }
        if (search.color) {
            let colorSearch = searched.filter((product) => product.specifications.color == search.color);
            resSearch = [...resSearch, ...colorSearch];
        }
        if (search.grammage) {
            let grammageSearch = searched.filter(
                (product) => product.specifications.grammage == search.grammage
            );
            resSearch = [...resSearch, ...grammageSearch];
        }
        if (search.nbfeuilles) {
            let nbfeuillesSearch = searched.filter(
                (product) => product.specifications.nbfeuilles == search.nbfeuilles
            );
            resSearch = [...resSearch, ...nbfeuillesSearch];
        }
        if (search.format) {
            let formatSearch = searched.filter(
                (product) => product.specifications.format == search.format
            );
            resSearch = [...resSearch, ...formatSearch];
        }
        // SearchProduct = searched.filter((product) => product.specifications.color == search.color);

        console.log('100 100 search', search);
        console.log('202 202 resSearch', resSearch);
    };


    $: searchProducts($Search);

The Product List Markup

{#if $Search.brand || $Search.color || $Search.grammage || $Search.format || $Search.nbfeuilles}
    {#each resSearch as product, index (index)}
                    <ProductItem
                        {product}
                        indexRow={index}
                        {activeRow}
                        on:activeRow={toggleActiveRow}
                        on:ProductDetails
                        on:Productorder
                        {listBox}
                    />
                {/each}
            {:else}
                {#each SearchProduct as product, index (index)}
                    <ProductItem
                        {product}
                        indexRow={index}
                        {activeRow}
                        on:activeRow={toggleActiveRow}
                        on:ProductDetails
                        on:Productorder
                        {listBox}
                    />
                {/each}
{/if}
```


1 Answers

The way the search logic is currently structured this probably will result in a logical "or". If you want to create an intersection (all searches have to apply), I would recommend combining the search logic into a single filter, this also prevents unnecessary iterations of the collection, something like:

results = items.filter(item =>
  (!search.color || item.color == search.color) &&
  (!search.size || item.size == search.size)
);

I.e. an item passes a filter if either no filter is defined or if the respective property matches the filter, combine all using && to get the intersection.

Example REPL

Related