Home > Back-end >  VUE3 compounding filters not working as intended
VUE3 compounding filters not working as intended

Time:12-26

so I'm trying to filter results using multiple filter options. ive tried a lot of different things and it works as intended with just 2 filters applied, but if i apply 3 or more filters to a search it will add more results to the search that don't match all the criteria.

meaning the more filters applied, the narrower the results should get distilled down to.

here is a gif showing what happens. https://imgur.com/a/gAX3ntA

here is the code I'm currently using. its bloated beyond all hell as I would have to think there is a simpler way to do this with compounding filters. plus if I want to add more filter options this way of doing things would quickly get insanely over complicated. please tell me there is a simpler way to do this lol.

I'm using VUE 3 with the composition API.

 const months = computed(() => {
  return documents.value.filter((plants) =>
    plants.months.includes(month.value)
  );
});
const plantType = computed(() => {
  return documents.value.filter(
    (plants) => plants.plantType == plantT.value
  );
});

const Zone = computed(() => {
  return documents.value.filter((plants) =>
    plants.Zone.includes(getZone.value)
  );
});
const toxicPets = computed(() => {
  return documents.value.filter((plants) =>
    plants.toxicPets.includes(toxic.value)
  );
});

const Combined = computed(() => {
  gettingThree = false;
  return documents.value.filter(
    (plants) =>
      plants.Zone.includes(getZone.value) &&
      plants.months.includes(month.value) &&
      plants.plantType == plantT.value &&
      plants.toxicPets.includes(toxic.value)
  );
});

const Combined2 = computed(() => {
  gettingTwo = true;
  gettingThree = false;
  return documents.value.filter(
    (plants) =>
      (plants.Zone.includes(getZone.value) &&
        plants.months.includes(month.value)) ||
      (plants.Zone.includes(getZone.value) &&
        plants.plantType == plantT.value) ||
      (plants.Zone.includes(getZone.value) &&
        plants.toxicPets.includes(toxic.value)) ||
      (plants.months.includes(month.value) &&
        plants.toxicPets.includes(toxic.value)) ||
      (plants.plantType == plantT.value &&
        plants.toxicPets.includes(toxic.value)) ||
      (plants.plantType == plantT.value &&
        plants.months.includes(month.value))
  );
});

const Combined3 = computed(() => {
  gettingTwo = false;
  gettingThree = true;
  return documents.value.filter(
    (plants) =>
      (plants.Zone.includes(getZone.value) &&
        plants.plantType == plantT.value &&
        plants.months.includes(month.value)) ||
      (plants.Zone.includes(getZone.value) &&
        plants.toxicPets.includes(toxic.value) &&
        plants.plantType == plantT.value) ||
      (plants.Zone.includes(getZone.value) &&
        plants.months.includes(month.value) &&
        plants.toxicPets.includes(toxic.value)) ||
      (plants.plantType == plantT.value &&
        plants.months.includes(month.value) &&
        plants.toxicPets.includes(toxic.value))
  );
});

const searchMatch = computed(() => {
  if (Combined.value.length > 0) {
    console.log("getting 4");
    return Combined.value.filter(
      (plant) =>
        plant.plantName.toLowerCase().indexOf(search.value.toLowerCase()) !=
        -1
    );
  }
  if (Combined3.value.length > 0 && gettingTwo == false) {
    console.log("getting 3");
    return Combined3.value.filter(
      (plant) =>
        plant.plantName.toLowerCase().indexOf(search.value.toLowerCase()) !=
        -1
    );
  }
  if (Combined2.value.length > 0 && gettingThree == false) {
    console.log("getting 2");
    return Combined2.value.filter(
      (plant) =>
        plant.plantName.toLowerCase().indexOf(search.value.toLowerCase()) !=
        -1
    );
  }

  if (
    month.value !== null &&
    getZone.value == null &&
    toxic.value == null &&
    plantT.value == null
  ) {
    return months.value.filter(
      (plant) =>
        plant.plantName.toLowerCase().indexOf(search.value.toLowerCase()) !=
        -1
    );
  }
  if (
    getZone.value !== null &&
    plantT.value == null &&
    month.value == null &&
    toxic.value == null
  ) {
    return Zone.value.filter(
      (plant) =>
        plant.plantName.toLowerCase().indexOf(search.value.toLowerCase()) !=
        -1
    );
  }
  if (
    plantT.value !== null &&
    month.value == null &&
    getZone.value == null &&
    toxic.value == null
  ) {
    return plantType.value.filter(
      (plant) =>
        plant.plantName.toLowerCase().indexOf(search.value.toLowerCase()) !=
        -1
    );
  }
  if (
    toxic.value !== null &&
    plantT.value == null &&
    month.value == null &&
    getZone.value == null
  ) {
    return toxicPets.value.filter(
      (plant) =>
        plant.plantName.toLowerCase().indexOf(search.value.toLowerCase()) !=
        -1
    );
  }

  return documents.value.filter((plant) => {
    return (
      plant.plantName.toLowerCase().indexOf(search.value.toLowerCase()) !=
      -1
    );
  });
});

CodePudding user response:

holy crap I figured it out on my own.

my solution is now WAY simpler than the solution I was working with in the OP and gives the desired results. see the this gif to see how it works now.

gif - https://imgur.com/mY8XksT

here is the code I came up with.

    //if a variable is null move on to the next filter or if the variable has a 
    //value then filter the results to include the value and move to the next  
    //filter. rinse and repeat for each filter.

    const Combined = computed(() => {
  return documents.value
    .filter((plants) => {
      return getZone.value == null || plants.Zone.includes(getZone.value); 
    })                                                                    
    .filter((plants) => {
      return month.value == null || plants.months.includes(month.value);
    })
    .filter((plants) => {
      return (
        plantT.value == null || plants.plantType.includes(plantT.value)
      );
    })
    .filter((plants) => {
      return toxic.value == null || plants.toxicPets.includes(toxic.value);
    });
});


//below takes the Combined filters property from above and runs it though another computed property to allow the user to type search in
//a input field. im running the search results through an array of multiple names per item since plants tend to have more than one name. so
//the user can search a varity of different names and still get a result that is correct. 

    const searchMatch = computed(() => {                               
      return Combined.value.filter((plant) => {
        let arr_lower = plant.otherNames.map(
          (item) => item.toLowerCase().indexOf(search.value.toLowerCase()) != -1
        ); //this function just returns true of false if the item matches the search results.
        return arr_lower.includes(true); //so here im just returning the arr_lower variable if it includes true.
      });
    });
  • Related