Home > front end >  how to fetch object with object
how to fetch object with object

Time:02-05

I am trying to fetch NAME from the list in the datatable. So,far below is the code that I have written.

enter image description here

HTML template -

<v-data-table :headers="headers" :items="topics" :footer-props="{'items-per-page-options': [5, 10, 20, 40]}" :items-per-page="10" item-key="srno">
   <template v-slot:item.skillName="{ item }">
       <span>{{ item.skillName || '-' }}</span>
   </template>
</v-data-table>
export default {
  data () {
    return {
      skills: [
        {
          name: ''
        }
      ],
      topics: [],
      headers: [
        { text: 'Sr No', value: 'srno', align: 'center', sortable: true },
        { text: 'Skills', value: 'skills', align: 'center' },
      ],
      skillName: [],
    }
  },
  created: async function () {
    await this.getAllList()
  },
  methods: {

    getAllList: async function () {
      try {
        this.isLoading = true
        let r = []
        let res = await http.get(`${CONSTANTS.API_URL}/api/getall-themes`, {
          params: {
            page: this.page - 1,
            size: this.pageSize
            // search: this.search
          }
        })
        this.topics = res.data.rows.map((item, index) => {
          item.srno = this.pageSize * (this.page - 1)   index   1
          item.skillName = item.Skills ? item.Skills.name : '-'
          return item
        })
              this.totalPages = res.data.totalPages
      } catch (e) {
        const errorMessage = (e && e.response && e.response.data.message) || e.message
        this.errMsg(errorMessage)
      } finally {
        this.isLoading = false
      }
    },

ERROR - skillName is going as undefined.

Excpeted Output - Writing,Singing should go in skillName

CodePudding user response:

Your don't declare a skillnName column in your header, only skills:

Try:

export default {
  data () {
    return {
      ...
      headers: [
        { text: 'Sr No', value: 'srno', align: 'center', sortable: true },
        { text: 'Skills',
           value: 'skills', // <---- probably should be skillName
           align: 'center' },
      ],
    }
  },

or

<v-data-table :headers="headers" :items="topics" :footer-props="{'items-per-page-options': [5, 10, 20, 40]}" :items-per-page="10" item-key="srno">
   <template v-slot:item.skills="{ item }"> <!-- <-------- slot name should match header.value -->
       <span>{{ item.skillName || '-' }}</span>
   </template>
</v-data-table>

Also, according to your data, you want to use an array here, so you need to create something printable from it. Try something like {{ item.Skills.map(s => s.name).join(',') || '-' }} in the template.

If you don't want complex expressions in the template, you have other options:

  • create a method on the component, so it would be {{ formatSkills(item) }}
  • if the items are instances of classes, creates a method on the class, so you can do: {{ item.getSkillsString() }}
  • after loading your data, create a property on each item with the joined value, something like:
async fetchData(){
  const items = await loadItems()
  items.forEach(item => item.skillsCsv = item.Skills.map(s => s.name).join(',')
}

The latter is usually the preferred option in Vue, it allows you to work without the slot, just set the new property in the header declaration:

{ text: 'Skills', value: 'skillsCsv', align: 'center' },

Note however that it is not reactive, if you add skills to an item, you have to rebuild the `skillsCsv´ prop manually (or you handle it through a setter).

Of course you can always use Skills directly in the template:

   <template v-slot:item.Skills="{ item }">
     <span v-for="skill in item.Skills" :key="skill.id">
       {{ skill.name}}
     </span>
   </template>
  • Related