I am very new to Vue and have been happy with the Vuetify framework for my project. However, I am unable to build a data table from an array, which I think is related to the payload. I only need to display a few values in the table, but would like them all there when I click a row.
Here is the (abbreviated) user payload:
[
{
"userId":3,
"firstName":"Sid",
"lastName":"Vicious",
"phoneNumber":"3132587777",
"devices":[
{
"deviceId":"1",
"deviceType":"phone"
"manufactureDate":null
}
]
},
{
"userId":4,
"firstName":"Johnny",
"lastName":"Rotten",
"phoneNumber":"3132587778",
"devices":[
{
"deviceId":"2",
"deviceType":"phone"
"manufactureDate":null
}
]
}
]
Here is the table:
<v-data-table
:headers="headers"
:items="users"
:items-per-page="10"
class="elevation-1 px-10 a-2"
#click:row="handleClick">
</v-data-table>
...
data() {
return {
headers: [
{
text: "Last Name",
align: "start",
sortable: true,
value: "lastName",
},
{
text: "First Name",
align: "start",
sortable: true,
value: "firstName",
},
{ text: "Phone", value: "phoneNumber" }
]
...
users = [
{
"userId":3,
"firstName":"Sid",
"lastName":"Vicious",
"phoneNumber":"3132587777",
"devices":[
{
"deviceId":"1",
"deviceType":"phone"
"manufactureDate":null
}
]
},
{
"userId":4,
"firstName":"Johnny",
"lastName":"Rotten",
"phoneNumber":"3132587778",
"devices":[
{
"deviceId":"2",
"deviceType":"phone"
"manufactureDate":null
}
]
}
]
}
And when I populate the users list, I get the following error:
[Vue warn]: Invalid prop: type check failed for prop "item". Expected
Object, got Array
The solution was to iterate over the user list, and for each item, do a array.push(item)
Related
I am using Apexchart's bar chart and noticed that I am not able to change the x-axis's labels, ie the categories. Below is the component:
<template>
<div>
{{magnitudeByFreq}}
{{chartOptions}}
<apex-chart width="500" type="bar" :options="chartOptions" :series="series"></apex-chart>
</div>
</template>
<script>
export default {
props: {
processedMouseData: null,
gradientCountByType: null,
magnitudeByFreq: null,
},
data: function() {
return {
chartOptions: {
chart: {
id: 'vuechart-example'
},
xaxis: {
categories: []//['Positive', 'Neutral', 'Negative']
}
},
series: [{
name: 'series-1',
data: []
}]
}
},
mounted() {
},
watch: {
gradientCountByType: function() {
console.log(this.series.data)
this.gradientCountByType ? this.series[0].data = this.gradientCountByType : console.log("Not working")
this.gradientCountByType ? this.chartOptions.xaxis.categories = ['Positive', 'Neutral', 'Negative'] : console.log("No xaxis")
},
magnitudeByFreq: function() {
this.magnitudeByFreq ? this.series[0].data = Object.values(this.magnitudeByFreq) : console.log("ABX")
this.magnitudeByFreq ? this.chartOptions.xaxis.categories = Object.keys(this.magnitudeByFreq) : console.log("ABA")
}
}
};
</script>
Currently the categories is set to []. This is because I want it to be filled by different data depending on which prop is using it. ie gradientCountByType or magnitudeByFreq.
The two lines below which are supposed to set the category:
this.gradientCountByType ? this.chartOptions.xaxis.categories = ['Positive', 'Neutral', 'Negative'] : console.log("No xaxis")
this.magnitudeByFreq ? this.chartOptions.xaxis.categories = Object.keys(this.magnitudeByFreq) : console.log("ABA")
They don't seem to update the category at all. I should however mention that what gets displayed in the template {{magnitudeByFreq}} and {{chartOptions}}, do reflect there is a change in the category variable:
{{chartOptions}} shows:
{ "chart": { "id": "vuechart-example" }, "xaxis": { "categories": [ "Positive", "Neutral", "Negative" ], "convertedCatToNumeric": false } }
and
{ "chart": { "id": "vuechart-example" }, "xaxis": { "categories": [ "+0", "+100", "+1000", "+2000" ], "convertedCatToNumeric": false } }
Why is the categories attribute not displaying correctly? For whatever reason, the categories are showing numbers.
My guess is by changing the data attribute doesn't actually update the chart.
Instead we should create a reference to the chart:
<apex-chart ref="radar" type="radar" height="350" :options="chartOptions" :series="series"></apex-chart>
Then we can update the data with updateSeries method and update the chartOptions with updateOptions method:
this.$refs.radar.updateSeries([{
name: 'Series 1',
data: [your_new_data_here] //ie [1,2,3,4]
}])
this.$refs.radar.updateOptions({
xaxis: {
categories: [your_new_categories_here] //ie ["a","b","c","d"]
}
})
<apex-chart ref="chart" :options="options" :series="series"/>
Chart component has refresh function. So we can re-render the chart.
this.series[0].data = [yourData];
this.options.xaxis.categories = [yourCategories]
this.$refs.chart.refresh();
in a normal way with out translation but i want to translate the two object array and bind into a component
<InfoNews
v-for="infonew in infonews"
:id="infonew.id"
:title="infonew.title"
:content="infonew.content"
/>
data() {
return {
infonews: [
{
id: "01",
title: "what we do",
content:"industke aecimen book. ",
},
{
id: "02",
title: "our mission",
content:"ggdddg",
},
],
};
Make infonews a computed property. The title and content of each should be the translation keys.
export default {
computed: {
infonews() {
return [
{
id: "01",
title: this.$t("what we do"),
content: this.$t("industke aecimen book"),
},
{
id: "02",
title: this.$t("our mission"),
content: this.$t("ggdddg"),
},
]
};
}
}
I have a table:
<b-table striped hover :items="coursesArray" :fields="fields"></b-table>
The data comes from
coursesArray: [
{
id: "1",
name: "foo",
teacherEmails: [{ 0: "sample1" }, { 1: "sample2" }, { 2: "sample3" }],
teacherIds: ["A1", "A2", "A3"],
},
],
And fields are:
fields: [
{ key: "id", label: "Course ID" },
{ key: "name", label: "Course Name" },
{
key: "teacherEmails",
label: "Teacher Email",
formatter: "teacherEmailTCellFormat",
},
{ key: "teacherIds", label: "Teacher ID" },
],
And this is how it's rendered without the formatter.
So, I added a custom formatter in fields to remove the brackets and curly braces.
The first problem I'm having is that looping over the value to return all the items in teacherEmails does not work.
teacherEmailTCellFormat(value) {
console.log(value)
value.forEach(item => {
return each[0]
}
}
The second problem, that I don't understand why it's happening, is that if I log the value passed to the formatter, it's clear the formatter function is called twice.
Any help or clearance will be appreciated.
You need to return an array, you can do this using Array#map:
new Vue({
el:"#app",
data: () => ({
fields: [
{ key: "id", label: "Course ID" },
{ key: "name", label: "Course Name" },
{ key: "teacherEmails", label: "Teacher Email", formatter: "teacherEmailTCellFormat" },
{ key: "teacherIds", label: "Teacher ID" },
],
coursesArray: [
{
id: "1",
name: "foo",
teacherEmails: [{ 0: "sample1" }, { 1: "sample2" }, { 2: "sample3" }],
teacherIds: ["A1", "A2", "A3"],
}
]
}),
methods: {
teacherEmailTCellFormat(value) {
return value.map((item, i) => item[i]);
}
}
});
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://unpkg.com/babel-polyfill#latest/dist/polyfill.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-table striped hover :items="coursesArray" :fields="fields"></b-table>
</div>
Note: I assumed the key represents the index of the item in the array, but you can change the mapping as you want. The main issue was returning the array.
I have a table with some filters in each column but when I type anything all the items disappear. The console does not return any error.
Here’s the code:
<template>
<div>
<b-table
id="the-table"
:per-page="perPage"
:current-page="currentPage"
:items="filteredItems"
:fields="fields"
>
<template slot="top-row" slot-scope="{ fields }">
<td v-for="field in fields" :key="field.key">
<input v-model="filters[field.key]" :placeholder="field.label" />
</td>
</template>
</b-table>
<b-pagination v-model="currentPage" :total-rows="rows" :per-page="perPage" aria-controls="the-table"></b-pagination>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
filters: {
option: "",
style: "",
stock: "",
},
items: [],
fields: [
{ key: "options", label: "Options", sortable: true },
{ key: "style", label: "Style", sortable: true },
{ key: "stock", label: "Stock", sortable: true },
{ key: "type", label: "Type", sortable: true },
{ key: "class", label: "Class.", sortable: true },
],
perPage: 15,
currentPage: 1,
};
},
created() {
this.getTable();
},
methods: {
getTable() {
axios
.get("./data/options.json")
.then((res) => (this.items = res.data))
.catch((error) => console.log(error));
},
},
computed: {
rows() {
return this.items.length;
},
filteredItems() {
return this.items.filter((d) => {
return Object.keys(this.filters).every((f) => {
return this.filters[f].length < 1 || this.filters[f].includes(d[f]);
});
});
},
},
};
</script>
I am trying to filter an array of objects like this:
[{"option": "ABEVH160", "style": "American", "stock": "ABEV3", "type": "CALL", "class": "ITM"},
{"option": "BBAS230", "style": "European", "stock": "BBAS3", "type": "PUT", "class": "ATM"},
{"option": "BBDC180", "style": "American", "stock": "BBDC4", "type": "CALL", "class": "OTM"}]
My goal is to be able to filter each of the columns individually:
Does anyone know what I’m missing?
The problem is with the condition:
return this.filters[f].length < 1 || this.filters[f].includes(d[f]);
d[f] is the full value and this.filters[f] is the search string. Obviously this does not work since it checks if the full word is contained in a substring. Simply invert the condition:
return this.filters[f].length < 1 || d[f].includes(this.filters[f]);
You can see it working here.
What you want seems to be something like DataTable Filter | Filter Row in PrimeVue. I tried to find something similar in the documentation of bootstrap-vue (documentation), but couldn´t find anything like that.
Maybe you are in a stage where you can still implement PrimeVue in your project. I´m using Filter Row from PrimeVue by myself and can recommend it.
I have a Vuetify Datatable component with server side data. I would like to sort the data in the client side with what I am currently displaying. But when I click on the column to sort it does not do anything. The column contains string values.
The following is my datatable:
<v-data-table
:page="page"
:pageCount="numberOfPages"
:headers="headers"
:items="services"
:options.sync="options"
:server-items-length="totalElements"
:loading="loading"
:custom-filter="filterOnlyCapsText"
class="elevation-1"
#update:page="updatePagination"
:items-per-page="itemsPerPage"
#update:items-per-page="setItemsPerPage"
>
My Vuejs code:
data() {
return {
headers: [
{
text: "Service",
value: "name",
sortable: true,
},
{
text: "Application",
value: "application.name",
},
{
text: "Description",
value: "description",
},
{
text: "Endpoint",
value: "endpoint",
},
{
text: "Environment",
value: "environmentList",
},
],
page: 1,
totalElements: 0,
numberOfPages: 0,
services: [],
loading: true,
options: {},
itemsPerPage: 0,
search: "",
};
},
options: {
handler() {
console.log("handler got called");
},
deep: true,
},
I am not sure what is needed to get the column to sort on the client side. Is there a listener that I need to hook in?
Thanks
You use server-side paging and need to implement this functionality by appropriate API calls when events
update:page, update:sortBy, update:options
emitted.
This is correct behavior because usually, you need to sort the whole data set, but not the current page.
Option which enable server-side behaviour:
server-items-length
Defining this prop will disable the built-in sorting and pagination.