Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return multiple values from a computed filter in Vue JS

I have a search box where when the user inputs an artist name and it shows a list of artists that match the user input.

I want to display the artist image next to the artist name in the search.

I have an object that contains the following. Artist Name as key and path to image as value

Radiohead: 'path_to_image',
Elliott Smith:'path_to_image'

I have a computed property that filters the artists name for search.

computed: {
filteredArtists() {
  return Object.keys(this.artistsList).filter((artist) => {
    return artist.match(this.artistName)
  }) 
}

},

and in my template I'm iterating throgh the values

<ul class="searchFliter" v-for="artist in filteredArtists">
  <li v-text="artist"></li>
</ul>

I can't find a way to manage that with computed values. I can easily iterate over my object and display both Artist name and Artist image but can't filter it.

Thanks in advance

like image 999
Qais Abou Jaoudé Avatar asked Sep 03 '17 16:09

Qais Abou Jaoudé


1 Answers

If you want to stick to your data structure then there are a number of ways you could manage to display the image along with the matching artists. Since you are essentially getting a list of keys to your artistList object in your computed property, you can use that key to get the path using artistList[artist].

<ul class="searchFliter" v-for="artist in filteredArtists">
  <li>{{artist}} <img :src="artistList[artist]"></li>
</ul>

However, if you want to instead, as you suggest in the title of your post, return multiple values from the list, then you can alter the computed property.

filteredArtists() {
  let matches = return Object.keys(this.artistsList).filter((artist) => {
    return artist.match(this.artistName)
  }) 

  return matches.map(m => ({name: m, imagePath: this.artistsList[m]}))
}

Here the computed property is finding all the matches and then creating a new object containing the name and image path. Use it in the template like so:

<ul class="searchFliter" v-for="artist in filteredArtists">
  <li>{{artist.name}} <img :src="artist.imagePath"></li>
</ul>

Of course, you can also choose a different data structure as well. Why not use use an array of artist objects?

[
  {name: "Radiohead", imagePath: "path to image"},
  {name: "Elliott Smith", imagePath: "path to image"}
]

In which case your computed property simply becomes

filteredArtists() {
  return this.artistsList.filter(m => m.name.match(this.artistName))
}
like image 80
Bert Avatar answered Sep 30 '22 04:09

Bert