Home > Software design >  How to target object in object in v-for
How to target object in object in v-for

Time:04-22

I have a list that displays all the songs in all of the artists.

I am able to do this by having v-for in a v-for.

However, i need the list to show a-z, I am able to do this with my computed property on one v-for, however it doesn't seem to work when I add v-for's in v-for's?

See my try <!--This is my Test-->?

How can I get this to work?

See my data structure also below!

This is my code try;

<template>
  <div >

<!-- Dynamic Headers -->
        <h1>{{header}}</h1>
        <br>
        <h2>{{header2}}</h2>  

<!-- Search Componenet -->
        <div >
              <br>
              <input  placeholder="Search Albums Here..." v-model="searchQuery"/>
        </div>

  <!-- This is my working list - Dynamic Song Route Button -->
            <div >
                <div v-for="album in datanew" :key="album.id">
                    <div  v-for="(item, i) in album.albums" :key="i">
                        <div  v-for="(itemtwo, i) in item.songsinalbum" :key="i">
                            <router-link  :key="item.songsinalbum" :to="'/songselected/'   item.song   '/artist/'   album.artist">
                                <div >{{itemtwo.song}}</div>
                            </router-link>
                        </div>
                    </div>
                </div>
            </div> 


<!--This is my test-->
            <div >
            <div v-for="itemss in sortedSongs" :key="itemss.id">
              {{ itemss.album }}
            </div>
            </div>
  </div>
</template>

<script>
import {datatwo} from '@/data2'
export default {
  data() {
  return {
  datanew: datatwo,
  header:"Browse by Song" ,
  header2: "Select a Song:",
    }
    },
  computed: {
    sortedSongs() {
      const res =[]
      this.datanew.albums.item.songsinalbum.forEach(a => a.album.forEach(s => res.push(s)))
      return res.sort(function(a, b) {
        if(a.album < b.album) { return -1; }
        if(a.album > b.album) { return 1; }
        return 0;
      })
    }
  }
}
</script>

Here is my data structure;

export const datatwo = [
{id: "1", artist: "aaxx", dateadded: "07/04/2022", artistroute: "/axxx", 
albums: [{album:'Shomati', songsinalbum: [
        { song : 'MaMaMa', keys: [
            {key: "Am"},
            {key: "Em"}
        ]}, 
        { song : 'Al Naharos Bavel', keys: [
            {key: "Am"},
            {key: "Em"}
        ]},  
        { song : 'Levinyomin', keys: [
            {key: "Am"},
            {key: "Em"}
        ]}, ]},   

        {album : 'Simcha', songsinalbum: [
            { song : 'Kolot', keys: [
                {key: "Am"},
                {key: "Em"}
            ]}, 
            { song : 'Kalu Kol Hakotzim', keys: [
                {key: "Am"},
                {key: "Em"}
            ]},  
            { song : 'Vehi Sheamdah', keys: [
                {key: "Am"},
                {key: "Em"}
            ]}, ]},   ]
},

Thanks!

CodePudding user response:

The problem here came from your computed value where you tried to push. The following line wont works because this.datanew.albums.item is undefined (because this.datanew.albums is an array)

this.datanew.albums.item.songsinalbum.forEach(a => a.album.forEach(s => res.push(s)))
      return res.sort(function(a, b) {

To sort data what I would do is loop through the albums and then push into the res array, the song list sorted.

 sortedAlbums() {
      const res = []
      this.datatwo.forEach(data => {
        data.albums.forEach(album => {
          album.songsinalbum.sort((a,b) => {
            if(a.song > b.song) return 1
            else return -1
          })
          console.log(album)
          res.push(album)
        })
      })
      
      return res
    }

Edit

If you want only the sorted song, what i recommand doing is pushing all the sond in an array and then sort the entire array.

This is not the most efficient way because you could have inserted directly at the good position but this is the easiest way.

sortedSong() {
      const res = []
      this.datatwo.forEach(data => {
        data.albums.forEach(album => {
          album.songsinalbum.forEach((song) => {
            res.push(song)
          })
        })
      })
      
      return res.sort((a, b) => {
        if(a.song > b.song) return 1
        else return -1
      })
    }

Working snippet

new Vue({
  el: '#app',
  computed: {
    sortedSong() {
      const res = []
      this.datatwo.forEach(data => {
        data.albums.forEach(album => {
          album.songsinalbum.forEach((song) => {
            res.push(song)
          })
        })
      })
      
      return res.sort((a, b) => {
        if(a.song > b.song) return 1
        else return -1
      })
    }
  },
  data: () => {
    return {
      datatwo: [{
        id: "1",
        artist: "aaxx",
        dateadded: "07/04/2022",
        artistroute: "/axxx",
        albums: [{
            album: 'Shomati',
            songsinalbum: [{
                song: 'MaMaMa',
                keys: [{
                    key: "Am"
                  },
                  {
                    key: "Em"
                  }
                ]
              },
              {
                song: 'Al Naharos Bavel',
                keys: [{
                    key: "Am"
                  },
                  {
                    key: "Em"
                  }
                ]
              },
              {
                song: 'Levinyomin',
                keys: [{
                    key: "Am"
                  },
                  {
                    key: "Em"
                  }
                ]
              },
            ]
          },

          {
            album: 'Simcha',
            songsinalbum: [{
                song: 'Kolot',
                keys: [{
                    key: "Am"
                  },
                  {
                    key: "Em"
                  }
                ]
              },
              {
                song: 'Kalu Kol Hakotzim',
                keys: [{
                    key: "Am"
                  },
                  {
                    key: "Em"
                  }
                ]
              },
              {
                song: 'Vehi Sheamdah',
                keys: [{
                    key: "Am"
                  },
                  {
                    key: "Em"
                  }
                ]
              },
            ]
          },
        ]
      }]
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div v-for="song of sortedSong">
    Song : {{ song.song }}
  </div>
</div>

  • Related