简体   繁体   中英

Filtering based on nested array return all

I'm trying to create a getter in Vuex that returns a filtered version of a state. The filter looks like this:

const state = () => ({
  recipes: [],
  appliedFilters: {
    engineers: null,
    categories: null,
    formats: null
  }
})

...

const getters = {

  getFilteredRecipes(state) {
    const appliedFilters = state.appliedFilters
    let recipesClone = state.recipes.slice(0)
    Object.keys(appliedFilters).forEach((key) => {
      var value = appliedFilters[key];
      if (value != null) {
        recipesClone.filter((recipe) => {
          return recipe.fields[key].some((field) => {
            return field.sys.id === value
          })
        })
      }
    })
    return recipesClone
  }

}

So the state.appliedFilters is an object that gets it's values changed from a module through an action, depending on what the user selects in a select field. If the user selects "Engineer A" in the select field for Engineers, an action is dispatched and a mutation sets state.appliedFilters.engineer to the value of the selection, in this case the ID for "Engineer A".

I want to loop through the key/value pairs of this object in order to see what choices that has been made and then continously filter state.recipes until it has gone through all the applied filters. So if I were to use the example above, the filter should return all recipes with "Engineer A" as engineer. If the filter value is null , it should skip the filtering and go on to the next key/value pair of the appliedFilters , in this case categories .

But each time the getter returns all of the recipes. Any idea what I'm doing wrong here?

recipesClone.filter doesn't actually change recipesClone , it just returns a new filtered list, so you should assign that new list to recipesClone to reflect changes in it. recipesClone = recipesClone.filter(...) .

That's one obvious problem I see in the code. See if that's enough to fix it.

In this function call, you're cloning the array, doing stuff using the applied filters array and then just returning the clone of the array:

 getFilteredRecipes(state) {
    const appliedFilters = state.appliedFilters
    let recipesClone = state.recipes.slice(0) // clone here
    Object.keys(appliedFilters).forEach((key) => { // loop here
      var value = appliedFilters[key];
      if (value != null) {
        recipesClone.filter((recipe) => {   // no return here
          return recipe.fields[key].some((field) => {
            return field.sys.id === value
          })
        })
      }
    })
    return recipesClone // return original
  }

If you want to return a filtered version of your recipes, you need to return the result of your filtering. It isn't exactly clear from your question how the filters related to your data, but something like this would return filtered data:

getFilteredRecipes(state) {

    const appliedFilters = state.appliedFilters
    let recipesClone = state.recipes.slice(0)
    let filteredRecipes = []
    Object.keys(appliedFilters).forEach((key) => {
      var value = appliedFilters[key];
      if (value != null) {
        const filtered = recipesClone.filter((recipe) => {
          return recipe.fields[key].some((field) => {
            return field.sys.id === value
          })
        })
        filteredRecipes = [...filteredRecipes, ...filtered] // ??
      }
    })
    return flteredRecipes;
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM