Skip to content

vuejs search filter with 2 v-for

I have the following filter computed

<script>
    export default {
        data() {
        return {
           columns:{},
           search:"",
           trovato:{},
        };
        },
        
        
        computed: {

       
           searchit() {

              const sear =this.search.toLowerCase().trim();
              if(!sear) return this.columns;
              Array.from(this.columns).forEach(element => {
                 element.filter((item) => {
    
 
                    if(item.toLowerCase().includes(sear)){
                     
                       this.trovato = item;
                       console.log(this.trovato);
                       return this.trovato;
                    }
                 
                })
             })
           }
    }
</script>

it works in a good way, the console.log(this.trovato) print the correct column that matches the name i searched.

the problem is i’m not able to print it in a v-list, in the beginning it displays all the values of the var columns{}, but after i type something it doesn’t display anything, it’s all blank. this is the code i’m using:

<v-list-item>
   <v-text-field append-icon="search" v-model="search" label="Cerca" ></v-text-field>
</v-list-item>
<v-list v-for="(item,index) in searchit" :key="index">
     <v-list-item v-for="ved in item" :key="ved.id">
         <v-list-item-content>
                                    
               <v-list-item-title >{{ved}}</v-list-item-title>
                                   
                                   
         </v-list-item-content>
     </v-list-item>
</v-list>

Answer

Array.prototype.filter returns a new array and doesn’t mutate the original array. (see documentation)

So here, you filter them but doesn’t assign the new filtered array to anything, so it goes into the void.

Plus, it really a bad practise to mutate a component data from a computed. You’re suppose to return a new object / array, derived from that data.

searchit() {
  const sear =this.search.toLowerCase().trim();

  if(!sear) { return this.columns; }

  const newColumns = this.columns.map(col => {
     return col.filter((item) => {
        if(item.toLowerCase().includes(sear)){
           this.trovato = item; // If possible, avoid setting data from a computed
           return this.trovato;
        }
      })
  })
  return newColumns;
}