Reputation: 6062
I am trying to parse a JSON string that my Laravel application serves to my Vue view. The JSON string can look like this:
{
"1":[ { "row":"Some text here on first column." },
{ "row":"And more text. Second row." },
{ "row":"Text!" }
],
"2":[ { "row":"2nd column text." },
{ "row":"" }
],
"3":[ { "row":"Even more text. But on the third column." }
]
}
Things to note here:
I am trying to parse the string as a table, like: https://jsfiddle.net/59bz2hqs/1/
This is what I have now:
<template>
<div>
<table>
<tbody>
<tr v-for="row in this.content">
<td>{{row}}</td>
</tr>
</tbody>
</table>
<div>
</template>
<script>
export default {
data() {
return {
content: []
}
},
created() {
Event.$on("document-was-processed", content => {
this.content = content;
});
}
}
</script>
Now above simply prints out the actual JSON string. Can anyone help me out on how to actually parse the content?
Thinking a bit more about this. I am actually not quite sure if my JSON string layout can even support my desired output.
Maybe like something below? Not quite sure.
{ "1":[
{ "text":"Some text here on first column."},
{ "text":"2nd column text."},
{ "text":"Even more text. But on the third column"}
],
"2":[
{ "text":"And more text. Second row." },
{ "text":"" },
{ "text":"" }
],
"3":[
{ "text":"Text!"},
{ "text":""},
{ "text":""}
]}
Then something like:
<table class="text-left w-full border-collapse m-3">
<thead>
<tr class="bg-gray-100">
<th v-for="(item, idx) in this.content" class="p-1">
{{idx}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, rid) in this.content">
<td v-for="(col, cid) in row">{{ col.text }} </td>
</tr>
</tbody>
</table>
Upvotes: 0
Views: 495
Reputation: 1309
You have to transpose your data before rendering it.
This is my dummy code
<script>
export default {
data() {
return {
dataTable: []
};
},
created() {
// Instead of fetching your content I put it in a local variable
let content = JSON.parse(`{
"1":[ { "row":"Some text here on first column." },
{ "row":"And more text. Second row." },
{ "row":"Text!" }
],
"2":[ { "row":"2nd column text." },
{ "row":"" }
],
"3":[ { "row":"Even more text. But on the third column." }
]
}`);
// Transform object in array of its values
let data = Object.values(content);
let colsLength = data.map(r => r.length);
let maxNumCols = Math.max.apply(Math, colsLength);
let colsArraySchema = Array.apply(null, Array(maxNumCols)).map((r, i) => i);
this.dataTable = colsArraySchema.map((col, i) => data.map(row => row[i]));
// For debug.
console.log(content);
console.log(data);
console.log(colsLength);
console.log(maxNumCols);
console.log(this.dataTable);
}
};
</script>
Now you can render the dataTable variable in your template. (Take care that you row array could contain undefined values)
<template>
<table border="1">
<tbody>
<tr v-for="(row, index) in dataTable" :key="index">
<td v-for="(cell, index) in row" :key="index">
<span v-if="cell">{{cell["row"]}}</span>
</td>
</tr>
</tbody>
</table>
</template>
You can see a live demo here: https://codesandbox.io/s/vue-json-transpose-dt915
I hope it helps you.
Upvotes: 2