0

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());
      }
    }
  }
//..

2 Answers 2

3

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.

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

4 Comments

Hi, @danh thank you to your feedback, I follow your instruction but it does not take me to my goal, I feel your answer is close to my solution.
@Omda - Did you press the "Run code snippet" button? It produces results that match my understanding of your question.
@danh- yah it is working fine, but it doesn't working when I put it with my code and using a computed property !
@Omda - I'm just a dabbler in Vue, but this answer seems to have a simpler setup than yours. Can you change to this simple setup and see what happens? stackoverflow.com/a/41791604/294949
0

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);
  }
})

1 Comment

thank you @deppem to contribute to my question, also I follow you the solution too but nothing happens when input field change, so how can I make it as computed property and then use it on my component?

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.