mercredi 20 janvier 2021

A bit stuck building a filter functionality

Im currently building a filter that gets executed upon click on react.

The initial value of the filter in the state is as follow:

    state = {
        checkBoxes: [],
        filter: { breedFor: [], temperaments: [], size: [] },
    };

I have a bunch of boxes that update the filter upon change here the logic below:

    onChangeCheckboxHandler = (event) => {
        // Creates the checkboxes for the State
        const copyOfCheckBoxes = this.state.checkBoxes;
        checkBoxesStateCreator(copyOfCheckBoxes, event);

        // MANAGES THE FILTER FOR THE STATE DEPENDING ON INPUT CHANGES
        const copyOfFilter = this.state.filter;
        const { breedFor, temperaments, size } = copyOfFilter;
        manageFiltersChanges(breedFor, temperaments, size, event);

        this.setState({
            checkBoxes: copyOfCheckBoxes,
            filter: { ...copyOfFilter },
        });
    };

Now, I have a sample of the data coming from an api that contains data about the items on the UI. Each of the object elements contains three different properties that I want to filter depending on the filters that the user selects.

This does not have to be an exact match, but that at least have one of the characteristics from the filter.

See below:

const dogsCharacteristicsData = [
    {
        id: 1,
        bredFor: ['hunting'],
        temperaments: [
            'stubborn',
            'curious,',
            'playful,',
            'adventurous,',
            'active,',
            'fun-loving',
        ],
        size: 'small',
    },
    {
        id: 2,
        bredFor: ['coursing', 'hunting'],
        temperaments: ['aloof', 'clownish,', 'dignified,', 'independent,', 'happy'],
        size: 'large',
    },
    {
        id: 3,
        bredFor: [],
        temperaments: ['wild', 'hardworking,', 'dutiful'],
        size: 'large',
    },
    {
        id: 4,
        bredFor: ['hunting'],
        temperaments: [
            'outgoing',
            'friendly,',
            'alert,',
            'confident,',
            'intelligent,',
            'courageous',
        ],
        size: 'medium',
    },
    {
        id: 5,
        bredFor: ['guarding'],
        temperaments: ['loyal', 'independent,', 'intelligent,', 'brave'],
        size: 'large',
    },
    {
        id: 6,
        bredFor: ['hunting'],
        temperaments: [
            'docile',
            'alert,',
            'responsive,',
            'dignified,',
            'composed,',
            'friendly,',
            'receptive,',
            'faithful,',
            'courageous',
        ],
        size: 'large',
    },
    {
        id: 7,
        bredFor: ['guarding'],
        temperaments: [
            'loving',
            'protective,',
            'trainable,',
            'dutiful,',
            'responsible',
        ],
        size: 'medium',
    },
    {
        id: 8,
        bredFor: ['hauling', 'pulling'],
        temperaments: [
            'friendly',
            'affectionate,',
            'devoted,',
            'loyal,',
            'dignified,',
            'playful',
        ],
        size: 'large',
    },
    {
        id: 9,
        bredFor: [],
        temperaments: [
            'friendly',
            'affectionate,',
            'devoted,',
            'loyal,',
            'dignified,',
            'playful',
        ],
        size: 'large',
    },
    {
        id: 11,
        bredFor: [],
        temperaments: [
            'strong',
            'willed',
            'stubborn,',
            'friendly,',
            'clownish,',
            'affectionate,',
            'loyal,',
            'obedient,',
            'intelligent,',
            'courageous',
        ],
        size: 'small',
    },
    {
        id: 12,
        bredFor: [],
        temperaments: [
            'friendly',
            'alert,',
            'reserved,',
            'intelligent,',
            'protective',
        ],
        size: 'medium',
    },
    {
        id: 13,
        bredFor: [],
        temperaments: [
            'friendly',
            'alert,',
            'reserved,',
            'intelligent,',
            'protective',
        ],
        size: 'small',
    },
    {
        id: 14,
        bredFor: ['hunting'],
        temperaments: [
            'kind',
            'sweet-tempered,',
            'loyal,',
            'independent,',
            'intelligent,',
            'loving',
        ],
        size: 'large',
    },
    {
        id: 15,
        bredFor: ['fighting'],
        temperaments: [
            'strong',
            'willed',
            'stubborn,',
            'friendly,',
            'clownish,',
            'affectionate,',
            'loyal,',
            'obedient,',
            'intelligent,',
            'courageous',
        ],
        size: 'medium',
    },
    {
        id: 17,
        bredFor: ['flushing', 'retrieving'],
        temperaments: [
            'friendly',
            'energetic,',
            'obedient,',
            'intelligent,',
            'protective,',
            'trainable',
        ],
        size: 'medium',
    },
];

I'm currently trying to design the logic and see if I can get it to work even though the code is long and inefficient. At the moment I wrote the following long code:

    searchRequestHandler = () => {
        const filterCopy = this.state.filter;
        const copyOfResults = this.state.results;
        const dogsCharacteristicsData = dataFromServerModelerUponSearch(
            this.props.dogs
        );
        const results = [];
        let resultsBredFor;
        let resultsTemperament;
        let resultsSize;

        if (
            filterCopy.breedFor.length !== 0 &&
            filterCopy.temperaments.length !== 0 &&
            filterCopy.size.length !== 0
        ) {
            console.log('all have something');
            resultsBredFor = dogsCharacteristicsData.filter((dog) => {
                return dog.bredFor.some((bredCharacteristic) =>
                    filterCopy.breedFor.includes(bredCharacteristic)
                );
            });

            resultsTemperament = dogsCharacteristicsData.filter((dog) => {
                return dog.temperaments.some((bredCharacteristic) =>
                    filterCopy.temperaments.includes(bredCharacteristic)
                );
            });

            resultsSize = dogsCharacteristicsData.filter((dog) =>
                filterCopy.size.includes(dog.size)
            );
        }

        if (
            filterCopy.breedFor.length !== 0 &&
            filterCopy.temperaments.length !== 0 &&
            filterCopy.size.length === 0
        ) {
            console.log('breedFor and Temperaments have something');

            resultsBredFor = dogsCharacteristicsData.filter((dog) => {
                return dog.bredFor.some((bredCharacteristic) =>
                    filterCopy.breedFor.includes(bredCharacteristic)
                );
            });

            resultsTemperament = dogsCharacteristicsData.filter((dog) => {
                return dog.temperaments.some((bredCharacteristic) =>
                    filterCopy.temperaments.includes(bredCharacteristic)
                );
            });
        }

        if (
            filterCopy.breedFor.length !== 0 &&
            filterCopy.temperaments.length === 0 &&
            filterCopy.size.length !== 0
        ) {
            console.log('breedFor and size have something');
            resultsBredFor = dogsCharacteristicsData.filter((dog) => {
                return dog.bredFor.some((bredCharacteristic) =>
                    filterCopy.breedFor.includes(bredCharacteristic)
                );
            });

            resultsSize = dogsCharacteristicsData.filter((dog) =>
                filterCopy.size.includes(dog.size)
            );
        }

        if (
            filterCopy.breedFor.length !== 0 &&
            filterCopy.temperaments.length === 0 &&
            filterCopy.size.length === 0
        ) {
            console.log('breedFor have something');
            resultsBredFor = dogsCharacteristicsData.filter((dog) => {
                return dog.bredFor.some((bredCharacteristic) =>
                    filterCopy.breedFor.includes(bredCharacteristic)
                );
            });
        }

        if (
            filterCopy.breedFor.length === 0 &&
            filterCopy.temperaments.length !== 0 &&
            filterCopy.size.length !== 0
        ) {
            console.log('size and Temperaments have something');

            resultsTemperament = dogsCharacteristicsData.filter((dog) => {
                return dog.temperaments.some((bredCharacteristic) =>
                    filterCopy.temperaments.includes(bredCharacteristic)
                );
            });

            resultsSize = dogsCharacteristicsData.filter((dog) =>
                filterCopy.size.includes(dog.size)
            );
        }

        if (
            filterCopy.breedFor.length === 0 &&
            filterCopy.temperaments.length !== 0 &&
            filterCopy.size.length === 0
        ) {
            console.log('Temperaments have something');
            resultsTemperament = dogsCharacteristicsData.filter((dog) => {
                return dog.temperaments.some((bredCharacteristic) =>
                    filterCopy.temperaments.includes(bredCharacteristic)
                );
            });
        }

        if (
            filterCopy.breedFor.length === 0 &&
            filterCopy.temperaments.length === 0 &&
            filterCopy.size.length !== 0
        ) {
            console.log('size have something');
            console.log(filterCopy.size);
            resultsSize = dogsCharacteristicsData.filter((dog) =>
                filterCopy.size.includes(dog.size)
            );
        }

        console.log(resultsBredFor, resultsTemperament, resultsSize);

The console.log above shows that the conditions, filters are working but then I don't know how I can aggregate the data together. I tried:

const results = [].contact(resultsBredFor, resultsTemperament, resultsSize)

but this does not work because, in size for example, it keeps showing small, medium or large and does not prioritise. Even filtering the duplicates does not work either.

Should I condition the size as well? so if the size is specified it only shows those items (dogs)?

Aucun commentaire:

Enregistrer un commentaire