I want to load data from my API into a mdbootstrap datatable.
How can I write a method, that calls the getPosts() API and writes the results into the rows[] array?
<template>
<mdb-datatable
:data="data"
striped
bordered
>
</template>
<script>
import { mdbDatatable } from 'mdbvue'
import api from '#/api'
export default {
name: 'TPanels',
components: {
mdbDatatable },
data: function () {
return {
loading: false,
posts: [],
model: {},
claims: '',
data: {
columns: [{
label: 'ID',
field: 'immo_id',
sort: 'asc'
},
{
label: 'Titel',
field: 'title',
sort: 'asc'
},
{
label: 'Preis',
field: 'price',
sort: 'asc'
}],
rows: [{
immo_id: XXX,
title: YYY,
price: ZZZ,
}],
}
}
},
async created () {
this.refreshPosts()
this.setup()
},
methods: {
async setup () {
this.claims = await this.$auth.getUser()
},
async isAuthenticated () {
this.authenticated = await this.$auth.isAuthenticated()
},
async refreshPosts () {
this.loading = true
this.posts = await api.getPosts()
}
}
</script>
In my template (vue.js) I can access the API for example with:
<tr v-for="post in posts" :key="post.id">
<td>{{ post.immo_id }}</td>
<td>{{ post.title }}</td>
<td>{{ post.url }}</td>
<td>{{ post.user_id }}</td>
</tr>
so I know that the API is working.
How can I do that please?
I managed to solve the problem by writing the method getTableData(). Important is to use push() on the array in order to have vue rendering the html newly.
},
async created () {
this.refreshPosts()
this.setup()
await this.getTableData()
},
},
getTableData () {
return api.getPosts().then(response => {
var index
let temp = response
console.log(temp)
for (index = 0; index < temp.length; ++index) {
this.data.rows.push({
title: temp[index].title,
immo_id: temp[index].immo_id,
price: temp[index].price
})
}
}
)
}
Related
I am a beginner and I try to reach API and show the table by using Vue.js and Vuetify.
I got data from API but I can't show it by v-data-table.
This is my code:
HTML part
<v-data-table :items="data" :headers="headers" :items-per-page="5">
<template slot="data" slot-scope="props">
<td>{{ props.data.userId }}</td>
<td>{{ props.data.id }}</td>
<td>{{ props.data.title }}</td>
</template>
</v-data-table>
script part
<script>
import axios from "axios";
export default {
name: "Current",
data: () => ({
items: ["albums", "todos", "posts"],
selected: "",
headers: [
{ text: "USER_ID", align: "start", sortable: false, value: "userId" },
{ text: "ID", value: "id" },
{ text: "TITLE", value: "title" },
],
data:[],
}),
methods: {
getData() {
axios
.get("https://jsonplaceholder.typicode.com/users/1/" + this.selected ,{dataType: 'json'})
.then((response) => { this.data = response.data;})
.catch((err) => alert(err));
},
},
mounted() {
this.getData();
}
};
</script>
Here is the output that I got
Here is what I want
I refactored your code, first of all when you fetch data from json placeholder there is a single object in the response, you have to push that object to data: [], instead of assigning. Also, it looks like your v-data-table template looks weird, and values from headers should match a key name from response data.
<template>
<v-app>
<v-data-table :items="data" :headers="headers" :items-per-page="5">
<template v-slot:items="props">
<td>{{ props.item.id }}</td>
<td>{{ props.item.name }}</td>
<td>{{ props.item.email }}</td>
</template>
</v-data-table>
</v-app>
</template>
<script>
import axios from "axios";
export default {
name: "App",
data: () => ({
items: ["albums", "todos", "posts"],
selected: "",
headers: [
{ text: "USER_ID", align: "start", sortable: false, value: "id" },
{ text: "EMAIL", value: "email" },
{ text: "NAME", value: "name" },
],
data: [],
}),
methods: {
getData() {
return axios
.get("https://jsonplaceholder.typicode.com/users/1/" + this.selected, {
dataType: "json",
})
.then((response) => {
this.data.push(response.data)
})
.catch((err) => alert(err));
},
},
mounted() {
this.getData();
},
};
</script>
I am trying to pass the data from methods into my empty array rows ,how i can easly pass it or how to call the API into rows
export default {
data () {
return {
data: {
headers: [
{ title: 'id', key: 'id' },
{ title: 'name', key: 'name' },
{ title: 'city', key: 'city' },
{ title: 'address', key: 'address' }
],
rows: []
}
}
},
components: {
BaseTable
},
methods: {
fetchUsers () {
this.$axios.get('https://605c40b36d85de00170d9a8f.mockapi.io/user/zurich')
.then(({ data }) => {
this.tableData = data
console.log(data)
})
}
}
}
When the response from your api arrives, you just have to add to your property declared in the method data.
new Vue({
el: "#app",
data() {
return {
row: []
}
},
methods: {
fetching() {
fetch('https://rickandmortyapi.com/api/character')
.then(res => res.json())
.then(res => {
console.log(res);
this.row = res.results; //Results added into array
})
.catch(err => console.error(err))
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="fetching">Fetch Api</button>
<div v-for="(item, key) in row" :key="key" style="margin: 2rem auto;" >
<p>- {{ item.id }} | {{ item.name }} | {{ item.status }}</p>
</div>
</div>
Hi guys I'm using sweetalerts to present alerts to my users, in this case, is a confirmation alert and it's working fine, the only thing is after complete I would like to refresh the module, not the whole page.
As right now I'm using this.$router.go(0) but is refreshing the whole page.
Or Update the Array so the table just shows the updated information:
<td class="text-xs-left">{{ records.item.phone }}</td>
<td class="text-xs-left">{{ records.item.date }}</td>
<td class="justify-center layout px-0">
<v-icon small
class="mr-4"
#click="editItem(records.item.email)">
visibility
</v-icon>
</td>
<td>
<v-icon small
v-on:click="showAlert(records.item.id)">
delete
</v-icon>
</td>
</template>
<v-alert slot="no-results" :value="true" color="error" icon="warning">
Your search for "{{ search2 }}" found no results.
</v-alert>
</v-data-table>
Script
<script>
import Vue from 'vue'
import api from '../store/api.js'
export default {
data() {
return {
pagination: {
descending: true,
rowsPerPage: 10
},
pagination2: {
rowsPerPage: 10
},
search: '',
search2: '',
records: [],
records2: [],
total: [],
confirm: false,
headers: [
};
},
created() {
api.GetAllInquiries().then((response) => {
this.records = response.data;
});
api.GetAllApplications().then((response) => {
this.records2 = response.data;
});
api.GetTotalInquiries().then((response) => {
this.total = response.data;
});
},
methods: {
editItem(email) {
this.$router.push({ name: 'Profile', params: { email: email } });
},
showAlert(id) {
ID: id
})
this.$swal.fire(
'Deleted!',
'Your file has been deleted.',
'success')
}
})
}
}
}
</script>
Basically just add the api call to the response portion of your showAlert function. I'm assuming that they are responsible for populating your tables.
showAlert(id) {
// Use sweetalert2
this.$swal.fire({
title: 'Are you sure?',
text: "You won't be able to revert this!",
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!'
}).then((result) => {
api.GetAllInquiries().then((response) => {
this.records = response.data;
});
api.GetAllApplications().then((response) => {
this.records2 = response.data;
});
api.GetTotalInquiries().then((response) => {
this.total = response.data;
});
if (result.value) {
this.$http.post('/api/deleteAddddddddpplication/',
{
ID: id
})
this.$swal.fire(
'Deleted!',
'Your file has been deleted.',
'success')
}
})
Component's template:
<v-layout>
<v-flex>
<v-data-table :headers="headers" :items="items" :search="search" :pagination.sync="pagination" :total-items="totalItems"
:loading="loading" class="elevation-1" :rows-per-page-items="sizes">
<template slot="items" slot-scope="props">
<td>{{ props.item.itemWebCode }}</td>
<td>{{ props.item.description }}</td>
<td>{{ props.item.sequence }}</td>
</template>
</v-data-table>
</v-flex>
Component's js code:
import itemHttpService from './../../../services/itemsHttpService.js'
export default {
name: 'items',
data: () => ({
items: [],
loading: true,
pagination: {},
totalItems: 0,
sizes: [10, 30, 60],
search: '',
headers: [
{ text: 'ItemWebCode', align: 'left', sortable: false, value: 'itemWebCode' },
{ text: 'Description', align: 'left', value: 'description', sortable: false },
{ text: 'Sequence', align: 'left', value: 'sequence', sortable: false }
],
}),
async mounted() {
await this.getItems();
},
watch: {
pagination: {
async handler() {
await this.getItems();
},
deep: true
}
},
methods: {
async getItems() {
this.loading = true;
var resp = await itemHttpService.getItems(this.pagination.page, this.pagination.rowsPerPage);
this.items = resp.data.items;
this.totalItems = resp.data.totalItems;
this.loading = false;
}
}
}
itemHttpService file:
import HTTP from './httpBase.js';
const service = {
getItems: async (page, size) => HTTP.get('items', {
params:{
page: page,
size: size
}
}),
};
export default service;
httpBase file:
import axios from 'axios';
const http = axios.create({
baseURL: 'http://localhost:53403/api/'
});
export default http;
I must say the data table rendering and working well. But found thing that looks
a bit strange for me and I'm pretty sure I did stupid mistake. When component initialization server receives 2 additional GET requests: http://prntscr.com/juo7yu Does anyone have an idea what I did wrong?
That bug was fixed in v1.1.0-alpha.6
I want to remove category_id from {{ columnValue }}, but what is the best way to to that, because i need category_id in the first part ?
<table>
<tr>
<td v-for="columnValue, column in record">
<template v-if="editing.id === record.id && isUpdatable(column)">
<template v-if="columnValue === record.category_id">
<select class="form-control" v-model="editing.form[column]">
<option v-for="column in response.joins">
{{ column.category }} {{ column.id }}
</option>
</select>
</template>
<template v-else="">
<div class="form-group">
<input class="form-control" type="text" v-model= "editing.form[column]">
<span class="helper-block" v-if="editing.errors[column]">
<strong>{{ editing.errors[column][0]}}</strong>
</span>
</div>
</template>
</template>
<template v-else="">
{{ columnValue }} // REMOVE category_id here!
</template>
</td>
</tr>
</table>
And the view (its the number under group i want to remove):
The DataTable view
The script:
<script>
import queryString from 'query-string'
export default {
props: ['endpoint'],
data () {
return {
response: {
table: null,
columntype: [],
records: [],
joins: [],
displayable: [],
updatable: [],
allow: {},
},
sort: {
key: 'id',
order: 'asc'
},
limit: 50,
quickSearchQuery : '',
editing: {
id: null,
form: {},
errors: []
},
search: {
value: '',
operator: 'equals',
column: 'id'
},
creating: {
active: false,
form: {},
errors: []
},
selected: []
}
},
filters: {
removeCategoryId: function (value) {
if (!value) return ''
delete value.category_id
return value
}
},
computed: {
filteredRecords () {
let data = this.response.records
data = data.filter((row) => {
return Object.keys(row).some((key) => {
return String(row[key]).toLowerCase().indexOf(this.quickSearchQuery.toLowerCase()) > -1
})
})
if (this.sort.key) {
data = _.orderBy(data, (i) => {
let value = i[this.sort.key]
if (!isNaN(parseFloat(value)) && isFinite(value)) {
return parseFloat(value)
}
return String(i[this.sort.key]).toLowerCase()
}, this.sort.order)
}
return data
},
canSelectItems () {
return this.filteredRecords.length <=500
}
},
methods: {
getRecords () {
return axios.get(`${this.endpoint}?${this.getQueryParameters()}`).then((response) => {
this.response = response.data.data
})
},
getQueryParameters () {
return queryString.stringify({
limit: this.limit,
...this.search
})
},
sortBy (column){
this.sort.key = column
this.sort.order = this.sort.order == 'asc' ? 'desc' : 'asc'
},
edit (record) {
this.editing.errors = []
this.editing.id = record.id
this.editing.form = _.pick(record, this.response.updatable)
},
isUpdatable (column) {
return this.response.updatable.includes(column)
},
toggleSelectAll () {
if (this.selected.length > 0) {
this.selected = []
return
}
this.selected = _.map(this.filteredRecords, 'id')
},
update () {
axios.patch(`${this.endpoint}/${this.editing.id}`, this.editing.form).then(() => {
this.getRecords().then(() => {
this.editing.id = null
this.editing.form = {}
})
}).catch((error) => {
if (error.response.status === 422) {
this.editing.errors = error.response.data.errors
}
})
},
store () {
axios.post(`${this.endpoint}`, this.creating.form).then(() => {
this.getRecords().then(() => {
this.creating.active = false
this.creating.form = {}
this.creating.errors = []
})
}).catch((error) => {
if (error.response.status === 422) {
this.creating.errors = error.response.data.errors
}
})
},
destroy (record) {
if (!window.confirm(`Are you sure you want to delete this?`)) {
return
}
axios.delete(`${this.endpoint}/${record}`).then(() => {
this.selected = []
this.getRecords()
})
}
},
mounted () {
this.getRecords()
},
}
</script>
And here is the json:
records: [
{
id: 5,
name: "Svineskank",
price: "67.86",
category_id: 1,
category: "Flæskekød",
visible: 1,
created_at: "2017-09-25 23:17:23"
},
{
id: 56,
name: "Brisler vv",
price: "180.91",
category_id: 3,
category: "Kalvekød",
visible: 0,
created_at: "2017-09-25 23:17:23"
},
{
id: 185,
name: "Mexico griller 500 gram",
price: "35.64",
category_id: 8,
category: "Pølser",
visible: 0,
created_at: "2017-09-25 23:17:23"
},
{
id: 188,
name: "Leverpostej 250 gr.",
price: "14.25",
category_id: 9,
category: "Pålæg",
visible: 1,
created_at: "2017-09-25 23:17:23"
},
}]
.. and so on......
I would recommend using a filter in Vue to remove the property, such as:
new Vue({
// ...
filters: {
removeCategoryId: function (value) {
if (!value) return ''
delete value.category_id
return value
}
}
})
An then use this in your template:
{{ columnValue | removeCategoryId }}
Update: I misunderstood the scope of the loop. This works, and I verified on jsfiddle: https://jsfiddle.net/spLxew15/1/
<td v-for="columnValue, column in record" v-if="column != 'category_id'">