I am trying to fetch NAME from the list in the datatable. So,far below is the code that I have written.
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>