Omda
Omda

Reputation: 177

how to search nested level JSON array

I have an API that has a structure in JSON format, and I need to search deeper into the third level of the array. I was using away but it doesn't work, so I was going to search for a library to do what I need someone tell me to go to the Loadash library, He said it will achieve what I am looking for. I implemented with on my way but is not working, so I need to know what is wrong with my code.

Edit

I updated my question and add HTML code to show you what I need it because your answers are not given me what I expect.

<temlate>
  <div>
    <div class="col-lg-6">
         <input type="email"
                class="form-control-in"
                id="exampleInputEmail1"
                aria-describedby="emailHelp"
                placeholder="search"
                v-model="search">
     </div>

    <div class="page-output" v-for="(asset, i) in doFilter" :key="i">
         <target-body :asset="asset"
                :search_by="search_by"></target-body>
    </div>
  </div>
</template>



domainAssets = 
[
   {
      "id":122,
      "name":"Game",
      "web_technologies":[
         {
            "name":"RequireJS",
            "categories":[
               "JavaScript Frameworks"
            ]
         }
      ]
   },
   {
      "id":123,
      "name":"Game2",
      "web_technologies":[
         {
            "name":"Composer",
            "categories":[
               "PHP Frameworks"
            ]
         }
      ]
   }
]

I am using vuejs to search:

//...
data(){
   return {
      search_by: 'web_technologies',
      search: 'PHP',
   }
},

computed: {
  ...mapState({
      domainAssets: state => state.Domain.domainAssets
  }),
  
  doFilter(){
    let self = this;
    return this.domainAssets.filter(function(domain){
      if(self.search_by == "web_technologies"){
         return _.includes(_.get(domain.web_technologies, self.search_by), self.search.toLowerCase());
      }
    }
  }
//..

Upvotes: 0

Views: 270

Answers (2)

danh
danh

Reputation: 62676

It can be done with standard array methods. Find the object where one of the web_technologies objects' categories contains the target string...

let searchBy = 'web_technologies'

function findDataWithCategory(category, data) {
  return data.find(datum => {
    return datum[searchBy].some(wt => {
      let searchableCategories = wt.categories.map(c => c.toLowerCase())
      return searchableCategories.some(cat => cat.includes(category.toLowerCase()))
    })
  })
}

const data = [{
    "id": 122,
    "name": "Game",
    "web_technologies": [{
      "name": "RequireJS",
      "categories": [
        "JavaScript Frameworks"
      ]
    }]
  },
  {
    "id": 123,
    "name": "Game2",
    "web_technologies": [{
      "name": "Composer",
      "categories": [
        "PHP Frameworks"
      ]
    }]
  }
]

console.log(findDataWithCategory('pHp', data))

EDIT improved to allow case insensitive search. A probably better way to do this (left to the reader) is to add a searchableCategories property to the data ahead of time, just once, when it's received. Edited again to check for substrings and to have a variable 'searchBy' key.

Upvotes: 3

depperm
depperm

Reputation: 10746

You can use lodash but your parameters aren't right. First for _.get you should just give the root element and then the path to the child. Next because you are looking for a part of an item I'd use join to turn the list into a string. Finally add an || so that you can check for normal case, you were searching for 'PHP'.toLowerCase() which even in a string wouldn't work

return domainAssets.filter(function(domain){
  if((self.search_by == "web_technologies"){
     return _.includes(_.get(domain, 'web_technologies[0].categories').join(), search.toLowerCase()) || _.includes(_.get(domain, 'web_technologies[0].categories').join(), search);
  }
})

Upvotes: 0

Related Questions