0

I want to loop through a JSON Array to search for a keyword. I am refering this thread to achieve this.

entries is a JSON array of stucture

[
    {"a": "something", "id": 54785, "b": ["each", "every", "one"]},
    {"a": "something", "id": 54785, "b": ["each", "every", "one"]},
    {"a": "something", "id": 54785, "b": ["each", "every", "one"]},
]

searchItem came from this custom component

<FormInput type="text"
    v-model="searchItem"
    @input="searchObject()"
    placeholder="Search here">
</FormInput> 

I placed my function in methods of component like this.

searchObject: function() {
  for (var i=0; i<this.entries.length; i++) {
    for (var key in this.entries[i]) {
      if (this.entries[i].key.indexOf(this.searchItem)!==-1) {
        this.result.push(this.entries[i])
      }
    }
  }
  return this.result
}

I get this error in console

TypeError: Cannot read property 'indexOf' of undefined

When I change in computed function and try [key] instead of .key

searchObject() {
  for (var i=0; i<this.entries.length; i++) {
    for (var key in this.entries[i]) {
      if (this.entries[i][key].indexOf(this.searchItem)!==-1) {
        this.result.push(this.entries[i])
      }
    }
  }
  return this.result
}

I am not getting anything pushed in result, neither I am getting any error in console. I tried to put console.log() command on my function, but again nothing on console.

4
  • What is this.result? Where is it defined? Commented Jan 25, 2019 at 13:41
  • in data(){return{result:[]}} Commented Jan 25, 2019 at 13:54
  • Which keys do you want to search within? Does your structure include nested objects and arrays? Commented Jan 25, 2019 at 14:12
  • I have many keys similar to a, id and b. I would like to search for likes of a and b. Commented Jan 25, 2019 at 14:24

2 Answers 2

2

Assuming that each object doesn't have any deeply nested objects or arrays inside it, you can use Object.values to get the values of your object.

With your current data, the returned values will contain another array so you have to flatten it by using .concat.apply to merge the values into one array.

Using the flattened array, you can then easily check if the current object contains your searchItem.

Edit: If you want to include an item to the result if the searchItem matches certain parts of the item values, you can use .join to concatenate your flattened values into a string.

See example below:

var app = new Vue({
  el: '#app',
  data: {
    result: [],
    searchItem: '',
    entries: [{
        "a": "something",
        "id": 54785,
        "b": ["one", "two", "three"]
      },
      {
        "a": "nothing",
        "id": 54785,
        "b": ["each", "every", "one"]
      },
      {
        "a": "everything",
        "id": 54785,
        "b": ["each", "every", "one"]
      },
    ]
  },
  methods: {
    searchObject: function() {
      this.result = []; // clear data, for demonstration only, remove if not needed

      for (var i = 0; i < this.entries.length; i++) {
        var values = [].concat.apply([], this.getValues(this.entries[i]));
        
        // you can also convert it to a string to match certain string parts
        values = values.join(',');
        
        if (values.indexOf(this.searchItem) !== -1) {
          this.result.push(this.entries[i])
        }
      }
    },
    getValues: function(object) {
      // use a polyfill in case Object.values is not supported by current browser
      return Object.values ? Object.values(object) : Object.keys(object).map(key => object[key]);
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<div id="app">
  <input type="text" v-model="searchItem" v-on:input="searchObject" placeholder="Search here" />
  <ul>
    <li v-for="i in result">{{i}}</li>
  </ul>
</div>

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much. Is there a way I can find something when I am searching some.
0

here is simple demo :

var app = new Vue({
  el: '#app',
  data: {
    result:[],
    searchItem:'',
    entries:
     [
{"a": "something", "id": 54785, "b": ["each", "every", "one"]},
{"a": "something", "id": 54785, "b": ["each", "every", "one"]},
{"a": "something", "id": 54785, "b": ["each", "every", "one"]},
]
  },methods:{
    searchObject:function(){
       for (var i=0; i<this.entries.length; i++) {
        for (var key in this.entries[i]) {
            if (key.indexOf(this.searchItem)!==-1) {
            this.result.push(this.entries[i])
            }
        }
      }
      if(this.searchItem && this.searchItem.length>0){
        return this.result;      
      }else{
         return this.result=[];
      }
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<div id="app">
  <input
type="text"
v-model="searchItem"
v-on:input="searchObject"
placeholder="Search here" />
<p>{{'searchItem :'+searchItem}}</p>
<ul>
<li v-for="i in result">{{i}}</li>
</ul>
</div>

3 Comments

you are searching in the key itself, i want to search it in value
which value you want to search , id or b array ?
There are many fields like a and b that I want to search on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.