"Discover the ins and outs of searching through every property in a Vue array

I'm currently working on my vue-app and I’m looking to implement a search feature for various topics. Here’s a sample of the data structure:

people: [
   {
    name: 'Mr.X',
    gender: 'Male',
    location: {
      address: 'some streetname',
      zipcode: '12345',
      city: 'Berlin',
      lng: 'longitude',
      lat: 'latitude',
    },
    skills: [
     { label: 'foo' },
     { label: 'bar' },
    ],
  },
 ...etc
]

To achieve this, I created a computed property in my component like so:

computed: {
   filteredResults() {
     return this.people.filter((person) => {
       let values = Object.values(person).join().toLowerCase();
       return values.includes(this.search.toLowerCase());
     })
   }
}

The HTML section related to the search component looks as follows:

<input type="text" v-model="search" />

<div v-for="(person, index) in filteredResults" :key="index">
    <p>{{ person.name }}</p>
</div>

As it stands, the search only checks against the name field. How can I include all properties for searching? In other words, when I search for “Berlin”, it should display all data associated with that keyword.

Answer №1

If I grasp your requirement accurately, you aim to sift through all the nested properties within the object using the search keyword.

Live Demo :

var vm = new Vue({
  el: '#vue-instance',
  data: {
    persons: [
       {
        name: 'Mr.X',
        gender: 'Male',
        location: {
          address: 'some streetname',
          zipcode: '12345',
          city: 'Berlin',
          lng: 'longitude',
          lat: 'latitude',
        }
      }, {
        name: 'Mrs.Y',
        gender: 'Female',
        location: {
          address: 'address 2',
          zipcode: '12345',
          city: 'alpha',
          lng: 'longitude',
          lat: 'latitude',
        }
      }
    ],
    search: ''
  },
  computed: {
    filteredList() {
       return this.persons.filter((person) => {
        const computedObj = { ...person,
            address: person.location.address,
            zipcode: person.location.zipcode,
            city: person.location.city,
            lng: person.location.lng,
            lat: person.location.lat
        }
         return Object.keys(computedObj)
              .some(key => ('' + computedObj[key]).toLowerCase().includes(this.search.toLowerCase()))
       })
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="vue-instance">
  <input type="text" v-model="search" />

  <div v-for="person in filteredList" :key="person.name">
      <p>{{ person.name }}</p>
  </div>
</div>

Answer №2

To optimize the search results and enhance performance, consider integrating filtering capabilities directly into the service itself. By passing filters in the request, you can shift the burden from the client to the database, which is better equipped for such tasks.

If conducting the filtering solely on the client-side is necessary, you can create a generalized filter function that allows comparisons based on various properties.

filteredList() {
     const filterObj = {
         'name': 'Mr. X',
         'gender': 'Female'
     };

     return this.persons.filter((person) => {
       // Evaluate if the object matches all defined filters in the filter object
       let isMatch = Object.entries(filterObj).map(([key, value]) => {
           if (typeof value === 'string')
               return person[key].toLowerCase().includes(value);
           if (typeof value === 'boolean')
               return person[key] === value;
           // Additional conditions can be added here
       }).every(i => i);

       return isMatch;
     })
},

Answer №3

To begin with, you must create an array that contains all your basic values and then apply a filter to it.

Below is the flatten() function which flattens all values from your data structure into a single array:

const persons = [
   {
    name: 'Mr.X',
    gender: 'Male',
    location: {
      address: 'some streetname',
      zipcode: '12345',
      city: 'Berlin',
      lng: 'longitude',
      lat: 'latitude',
    },
    skills: [
     { label: 'foo' },
     { label: 'bar' },
    ],
  },
]

const flatten = (input) => {
  if (typeof input === 'object') {
    return (Array.isArray(input) ? input : Object.values(input))
      .reduce((acc, x) => acc.concat(flatten(x)), [])
  } else {
    return [input]
  } 
}

console.log(flatten(persons))
console.log(flatten(persons).includes('Berlin'))

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to store selected items from a multi-select box in AngularJS that is generated using ng-repeat?

I have a scenario where I need to handle a group of select boxes instead of just one. Each select box holds a different option, and when the user changes their selection, I want to save that value in a variable or an array. I've managed to do this for ...

Switch between using the useState hook by toggling it with the MUI Switch

Looking to implement a custom Dark Mode feature for a specific element on my create-react-app website using MUI. I have successfully implemented the Switch to change the state on toggle, but I am having trouble figuring out how to toggle it back and fort ...

Converting a JavaScript timestamp into a human-readable date and time using as.POSIXct in R

Is there a way to convert a timestamp from this format into a readable human date? I have generated the timestamp using JavaScript: Date.now(); An example of the output is: 1468833354929 After storing it in a database, when I attempt to convert it usi ...

Having a text input that is dependent on choosing a particular item from a list

As someone who is new to VueJs and JS, I have a question regarding my page setup. I want a text input box to only be visible when the user selects the document type 'Write Individual'. However, my current syntax seems to be incorrect as it's ...

Page freezing due to JQuery scroll event

I successfully implemented a trigger that checks if an element is within the visible viewport and added it to the scroll event. While this works smoothly on some pages, I noticed that on larger pages it causes the page to freeze. In Firefox, I experienced ...

Using dual index variables in Angular 4's ngFor loop for iterating through arrays

Is there a way to generate unique index numbers for items printed only on Saturdays? Specifically, I want the index to start from 0 once Saturday begins and continue incrementing. The rest of the options should have the same index numbers. Any suggestions ...

Display array values in JavaScript from different arrays

I'm currently working on extracting data from my API to plot it in a graph. Specifically, I am interested in obtaining an array that contains only the 'date' values. Here's what I have managed to extract so far: https://i.sstatic.net/0 ...

How can I incorporate variables within a style tag in an Angular template?

I'm currently working on an Angular 5 application and I need to be able to apply dynamic CSS within the style tag in the template. I've tried a few solutions but so far, none have worked. app.component.ts customCss : any; constructor(){} ngOn ...

Mocking objects in unit test cases to simulate real-life scenarios and test the

How do I pass a mocked event object and ensure it is validated? onCallFunction() { const eventValue = event; if (!eventValue.relatedTarget || !eventValue.relatedTarget.last.contain('value')) { super.onCallFuncti ...

Unable to remove the dropotron transparency from the menu dropdown

I'm currently working with a CSS template that includes a Dropotron for JQuery menu animation. I've run into a problem trying to remove the transparency effect on the dropdown menu. Oddly enough, the second dropdown labeled "About Us" appears sol ...

What is the best way to extract values from promises that are still pending?

Having some issues with the code below and unable to achieve the desired output. Any help in identifying what's wrong would be greatly appreciated. Thanks! Here is the code: // Making http requests const getJSON = require('get-json'); ...

Locate and dismiss a toast message (Toastr)

I have a webpage where I can add multiple popup notifications called toasts dynamically using the toastr plugin found at https://github.com/CodeSeven/toastr. Each toast has an Ok link that, when clicked, should only close that specific toast and not all v ...

What is the proper way to change this JavaScript variable into JSON format?

I have a JavaScript variable containing data that I need to convert into valid JSON format for easier parsing. The current variable structure is as follows: { "machines": [{ "category": "Category 1", "items": [{ "name": "Te ...

The conditional statement is malfunctioning when both dates are identical

If the deadline date is today or in the future, I want to display the deadline date. If the date has passed, I want to display the word 'Closed'. Below is the code I am using, which works except for when the deadline and today's date are th ...

Get a Blob as a PNG File

Hope you had a wonderful Christmas holiday! Just to clarify, I am new to JS and may make some unconventional attempts in trying to download my Blob in PNG format. I am facing an issue with exporting all the visual content of a DIV in either PDF or image ...

Updating component data in VueJS can sometimes be tricky, especially when dealing with the same

I have a route called '/posts' which includes a created() function that fetches data from an API using GET and displays the data on the page. Recently, I added a navbar to all pages with an input field for searching posts by tags. This tag-based ...

Subtract the initial character from the result

What is the best way to eliminate the first letter from a string in this scenario? d[],e[], [dsh,sj] After analyzing the data, I realized that I need to remove the first letter before every comma (,). I tried storing the data and using a for loop, but en ...

Issue: Database not updating after input via AJAXExplanation: Despite submitting new data through AJAX, the

I've been struggling to display the UPDATED database on my initial html page after submitting new information. Despite successfully updating the database using AJAX, I can only see the outdated version. Any assistance in resolving this issue would be ...

Enhancing validation in an established tutorial using Backbone

After following Thomas Davis' tutorial, I decided to enhance the age field by adding validation. However, my attempts to modify the Model as shown below have been unsuccessful: var User = Backbone.Model.extend({ validate: function(attr, error) { ...

What are the steps for implementing Jquery Datatables Ellipsis renderer with a template field link button?

When I utilize this with the Asp-bound field, everything works perfectly. Observe how column one is Ellipsed. https://i.sstatic.net/5knrN.png However, when used on a template field link button, it returns blank. It appears blank; I'm not sure what ...