Here the is the b-table, it will display a column of food(s)
<b-table :fields="Fields" :items="ITEMS">
<template #cell(food)="data">
{{data.item.food}}
</template>
</b-table>
//The column
Fields() {
return [{key: 'food', label: 'food'}];
}
Currently the data looks something like this:
[
{
"food": "taco"
},
{
"food": "burrito"
}
]
It writes the values all in a single column to the table.
I need the table to be able to handle data that looks like this
[
{
"foods": [
{
"food": "taco"
},
{
"food": "burrito"
}
]
},
{
"foods": [
{
"food": "soup"
},
{
"food": "rice"
}
]
}
]
//The column, probably not correct but I'm trying to get it to read every "food" under all "foods"
Fields(){
return [{key: 'foods.food', label: 'food'}];
},
This would write the data to the table same as before, in one column.
<!-- Everytime a "foods" array is found, loop through all the food items that it holds -->
<b-table :fields="Fields" :items="ITEMS">
<template #cell(foods)="data">
<div v-for="entry in data.item.foods" :key="entry.food">
<!-- **THIS TEMPLATE DOES NOT WORK, but if it did then it would count as a solution!** -->
<template #cell(food)="data">
{{food}}
</template>
</div>
</template>
</b-table>
To get just a single column table with a list of food names, the bootstrap-vue table wants data to look like this...
fields: ['food'],
items: [
{ food: "taco" },
{ food: "soup" },
// ...
]
I think I understand from the OP (thanks for the edits) that the source data looks differently. The job, then, is to transform the source data into what the table needs. This can best be done with a computed prop. The benefit is that the transformation will be cached and it will remain reactive to changes in the source data.
This is all you need to turn the data described in the OP into the data needed by the table:
computed: {
items() {
// presuming source data is available and in the OP format
return this.sourceData.map(d => d.foods).flat()
},
}
Here's a demonstration of that computation working:
window.onload = () => {
new Vue({
el: '#app',
data: function() {
return {
sourceData: [],
fields: [{ key:'food', label:'The Foods' } ]
}
},
mounted() {
this.sourceData = [
{ foods: [ { food: "taco"}, { food: "burrito"} ] },
{ foods: [ { food: "soup"}, { food: "rice"} ] },
];
},
computed: {
items() {
return this.sourceData.flatMap(d => d.foods);
}
},
})
}
<script src="https://unpkg.com/vue@2.6.10/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.0.0-rc.27/dist/bootstrap-vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/bootstrap-vue@2.0.0-rc.27/dist/bootstrap-vue.css"/>
<link rel="stylesheet" href="https://unpkg.com/bootstrap@4.3.1/dist/css/bootstrap.min.css"/>
<div id="app">
<b-table :items="items" :fields="fields"/>
</div>
This would write the data to the table same as before, in one column.
To achieve this, your items
array should be a flat array. Hence, you can convert the input array into a flat array first in mounted()
life cycle hook and then bind in the <v-table>
.
Demo :
window.onload = () => {
new Vue({
el: '#app',
data() {
return {
fields: [{key: 'food', label: 'food'}],
items: [
{
"foods": [
{
"food": "taco"
},
{
"food": "burrito"
}
]
},
{
"foods": [
{
"food": "soup"
},
{
"food": "rice"
}
]
}
]
}
},
mounted() {
this.items = this.items.map(d => d.foods).flat();
}
})
}
<script src="https://unpkg.com/vue@2.6.10/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.0.0-rc.27/dist/bootstrap-vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/bootstrap-vue@2.0.0-rc.27/dist/bootstrap-vue.css"/>
<link rel="stylesheet" href="https://unpkg.com/bootstrap@4.3.1/dist/css/bootstrap.min.css"/>
<div id="app">
<b-table :items="items" :fields="fields">
</b-table>
</div>