I am trying to iterate through an object, pulled from database using axios. I am able to make the object show up in my data table, but i am unable to make it break the data to the specified columns
first snippet is the parent component. the tr and td for the actual list i broke out to a separate component but that may need to be fixed.
<template>
<div class="container">
<router-link to="/add" class="btn btn-primary btn-sm float-
right">AddClient</router-link>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Type</th>
<th scope="col">Email</th>
<th scope="col">Phone</th>
<th></th>
</tr>
</thead>
<client-info></client-info>
</table>
</div>
</template>
<script>
import ClientInfo from '#/components/clientslistexperience/ClientInfo'
export default {
name: 'ClientsList',
components: {
ClientInfo
},
methods: {
},
}
</script>
enter code here
next is the component iterating through the data to be show in the table
<template>
<div class="client-info">
<tbody>
<tr v-for="(client, index) in clients" v-bind:key="index"
:client="client">
<th scope="row">{{ client.id }}</th>
<td>{{ client.name }}</td>
<td>{{ client.type }}</td>
<td>{{ client.email }}</td>
<td>{{ client.phone }}</td>
</tr>
</tbody>
</div>
import { mapState } from 'vuex'
export default {
name: 'client-info',
props: {
id: Array,
type: String,
name: String,
email: String,
phone: Number,
},
computed: {
...mapState ([
'clients'
])
},
created() {
this.$store.dispatch('retrieveClients')
}
}
</script>
enter code here
last is the vuex store where axios request is being made. now i know using the vuex for smaller projects is over kill but im intending for this to become rather large so this is the method ive chosen. any help would be awesome! Thanks.
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
axios.defaults.baseURL = 'http://client-api.test/api'
export default new Vuex.Store({
state: {
clients: []
},
mutations: {
retrieveClients(state, clients) {
state.clients = clients
},
},
actions: {
retrieveClients(context) {
axios.get('/clients')
.then(response => {
// console.log(response)
context.commit('retrieveClients', response.data)
})
.catch(error => {
console.log(error)
})
}
}
})
enter image description here
In fact, you need to remove the div root element in your ClientInfo.vue component.
Replace the div by tbody and it solve your problem ;)
<template>
<tbody class="client-info">
<tr v-for="(client, index) in clients"
:key="index">
<td>{{ client.id }}</td>
<td>{{ client.name }}</td>
<td>{{ client.type }}</td>
<td>{{ client.email }}</td>
<td>{{ client.phone }}</td>
</tr>
</tbody>
</template>
Full demo here > https://codesandbox.io/s/v8vw0z89r7
Related
What does this error mean?
error message
this happens when I put my filteredData variable inside the tr tag of the table.
<table id="table">
<tr>
<th>First name</th>
<th>Last Name</th>
<th>Email</th>
<th>Original email</th>
<th>Actions</th>
</tr>
<template>
<tr v-if="(fiteredData = '')">
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr
v-else
v-for="data in filteredData"
:key="data.ind_id"
:value="data.ind_id"
>
<td>{{ data.first_name }}</td>
<td>{{ data.last_name }}</td>
<td>{{ data.email }}</td>
<td>{{ data.email }}</td>
<td>
<button #click="sendProps(data)">
<i class="fa-regular fa-edit" aria-hidden="true"></i>
</button>
</td>
</tr>
</template>
</table>
This is my method:
data() {
return {
fetchedData: "",
filteredData: "",
};
},
methods: {
searchResult(e) {
this.filteredData = this.fetchedData.filter((data) => {
return data.email.toLowerCase().includes(this.email.toLowerCase());
});
e.preventDefault();
console.log(this.filteredData);
}
fetchedData get the data from this:
async mounted() {
await axios.get("http://localhost:5000/individuals").then((result) => {
this.fetchedData = result.data;
console.log(this.fetchedData);
});
},
I am guessing this: <tr v-if="(filteredData = '')"> should be: <tr v-if="filteredData === ''">, or even beter: v-if="!filteredData.length". You've misspelled the variable name and are accidentally setting it to an empty string rather than doing a comparison (we've all been there, I'm sure)
On a related note, I would initialize fetchedData and filteredData as empty arrays, not strings, because v-for is meant to iterate over objects and arrays, not strings (even though it's probably smart enough to handle it).
When I encountered this problem in the past it was that the browser itself had an issue and opening my application in a new private window worked.
I have a Vue application and I am trying to display each 'object' in its own table row. However, I can only get it to display each object in one column or I can get it to a point where each element is in its own row (image below). How would I make it so '0 BTC AUD 14,745.3' is in the first row and then the next object '1 ETH AUD 312.14' is displayed in the second row. I am new to Vue and was wondering if anyone was able to help me out
I have attached an image below as well as my current code, thank you!
<template>
<div class="main">
<div id="container" v-for="(index) in coin" :key="index">
<table class="coins">
<thead>
<tr class="header">
<th>Rank</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<td>{{ index }}</td>
</tbody>
</table>
</div>
</div>
</template>
<script>
import axios from 'axios'
var limit = 20
export default {
name: 'ex',
data: () => ({
coin: []
}),
created () {
axios.get('https://min-api.cryptocompare.com/data/top/totalvolfull?limit=' + limit + '&tsym=AUD')
.then(response => {
for (var i = 0; i < limit; i++) {
this.coin.push(i, response.data.Data[i].CoinInfo.Name, response.data.Data[i].DISPLAY.AUD.PRICE)
// console.log(this.coin[i])
}
})
.catch(e => {
this.errors.push(e)
})
}
}
</script>
Change the way you are pushing data into your coin array, because here in every iteration you are pushing three items (an index, a coin name and a value) into the array but what you want to do is push a single item (an array or object) containing all this information. For code clarity also change the name of the coin array into coins. Something like this should work:
this.coins.push([i, response.data.Data[i].CoinInfo.Name, response.data.Data[i].DISPLAY.AUD.PRICE])
Then change the iteration in your template. First thing change the v-for to something like this:
<div id="container" v-for="(coin, index) in coins" :key="index">
and then when you print the content:
<tbody>
<td>{{ coin[0] }}</td>
<td>{{ coin[1] }}</td>
<td>{{ coin[2] }}</td>
</tbody>
I didn't test this, but I hope the general idea is enough to get you on the right direction.
maybe change how did you create this object
instead do that:
this.coin.push(i, response.data.Data[i].CoinInfo.Name, response.data.Data[i].DISPLAY.AUD.PRICE)
Do something like that
const coinObject = {
index: i,
name:response.data.Data[i].CoinInfo.Name,
price: response.data.Data[i].DISPLAY.AUD.PRICE
}
this.coin.push(coinObject);
and then you can loop like that in your template:
<div id="container" v-for="(coinItem, index) in coin" :key="index">
<table class="coins">
<thead>
<tr class="header">
<th>Rank</th>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<td>{{ coinItem.index }}</td>
<td>{{ coinItem.name }}</td>
<td>{{ coinItem.price }}</td>
</tbody>
</table>
</div>
i want create web crud with vue+axios. but i don't understand how create checbox check all use vue use data api, which later for delete all,
I use this method but the data doesn't appear
sorry i just learned vue + axios
https://pastebin.com/iJDPU0AB
<table id="" class="table table-bordered table-striped">
<thead>
<tr>
<th><input type="checkbox" v-model="selectAll"></th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody id="target_listing">
<tr v-for="tl in target_listing">
<td><input type="checkbox" v-model="selected" :value="user.id" number></td>
<td>{{ tl.id_target_mst_status }}</td>
<td>{{ tl.category }}</td>
<td>{{ tl.first_name }}</td>
<td>{{ tl.last_name }}</td>
<td>{{ tl.revisit }}</td>
<td>{{ tl.visit_status }}</td>
</tr>
</tbody>
</table>
my app.js
var myTable = new Vue({
el: '#target_listing',
data(){
return{
target_listing:null
}
selected: []
},
mounted(){
axios
.get('http://localhost/warna2/public/api/target_listing')
.then(response => (this.target_listing = response.data.data))
.catch(error => {
console.log(error)
this.errored = true
})
},
computed: {
selectAll: {
get: function () {
return this.target_listing ? this.selected.length == this.target_listing.length : false;
},
set: function (value) {
var selected = [];
if (value) {
this.target_listing.forEach(function (user) {
selected.push(user.id);
});
}
this.selected = selected;
}
}
}
})
I need to add rows in table #dynamic but table static shouldn't be affected.
If I click the button with the code below, both tables will be updated, because they have the same v-for. And, if I put a v-for in a v-for my data won't be fetched. I can't figure out how to "unique" the first table.
vue/html:
<template>
<table id="dynamic">
<tr v-for="rows in list">
<td>Content of row {{ rows.item1 }}</td>
<td>Content of row {{ rows.item2 }}</td>
</tr>
</table>
<div #click="block = !block">click</div>
<table id="static">
<tr v-for="rows in list">
<td>Content of row: {{ rows.item3 }}</td>
<td>Content of row: {{ rows.item4 }}</td>
</tr>
</table>
</template>
js
export default {
data: function () {
return {
list: [],
};
},
props: ['channelId'],
mounted() { },
created() {
this.fetchChannel(this.channelId);
},
methods: {
fetchChannel: function (channelId) {
$.getJSON('/api/channel/' + channelId, function (data) {
this.list = data;
}.bind(this));
},
}
}
I found some examples for help like this codepen or fiddle but I am not successful with it.
If the #static table is truly never meant to update when the its data changes, this would be a case for using the v-once directive:
<table id="static" v-once>
<tr v-for="rows in list">
<td>Content of row: {{ rows.item3 }}</td>
<td>Content of row: {{ rows.item4 }}</td>
</tr>
</table>
This will tell Vue to render the table only once and then ignore it upon any re-renders.
Here's a fiddle.
I have a table like this that displays data including several navigation properties :
<table class="table afcstandings">
<thead>
<tr>
<th>team</th>
<th>coach</th>
<th>w</th>
<th>l</th>
<th>t</th>
<th>fa</th>
<th>agst</th>
<th>diff</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let standing of standingsAFCEast">
<!-- property binding rather than interpolation-->
<td>{{ standing.team.teamName }}</td>
<td>{{ standing.team.coach.coachName }}</td>
<td>{{ standing.won }}</td>
<td>{{ standing.lost }}</td>
<td>{{ standing.tied }}</td>
<td>{{ standing.pointsFor }}</td>
<td>{{ standing.pointsAgainst }}</td>
<td>{{ standing.pointsDifference }}</td>
</tr>
</tbody>
</table>
Here is the data structure that is being read :
[{"team":{"teamId":22,"teamName":"Carolina Panthers","coach":{"coachId":61,"coachName":"J Smith"},"division":{"divisionId":2,"divisionName":"NFC West"},"headerImage":"","logoImage":"","hex":"","r":null,"g":null,"b":null},"won":2,"lost":1,"tied":0,"pointsFor":82,"pointsAgainst":62,"pointsDifference":20}]
My question is, how do I display this data using ngx-datatable? I have tested with 3 fields, teamName, coachName and won, and am able to display the won field, but not the others, as I am not sure how to drill down into the team object or the coach object.
<ngx-datatable class="ngx-datatable" [rows]="standingsAFCEast">
<ngx-datatable-column name="team.teamName" [width]="300"></ngx-datatable-column>
<ngx-datatable-column name="team.coach.coachName"></ngx-datatable-column>
<ngx-datatable-column name="won"></ngx-datatable-column>
</ngx-datatable>
Any advice would be really appreciated!
After looking at the basic examples, I made this work (Plunker here):
#Component({
selector: 'my-app',
template: `
<div>
<ngx-datatable
[rows]="rows"
[columns]="columns"
[columnMode]="'force'"
[headerHeight]="50"
[footerHeight]="50"
[rowHeight]="'auto'"
[reorderable]="reorderable">
</ngx-datatable>
</div>
`
})
export class AppComponent {
standingsAFCEast = [{
"team":{
"teamId":22,
"teamName":"Carolina Panthers",
"coach":{
"coachId":61,
"coachName":"J Smith"
},
"division":{
"divisionId":2,
"divisionName":"NFC West"
},
"headerImage":"",
"logoImage":"",
"hex":"",
"r":null,
"g":null,
"b":null
},
"won":2,
"lost":1,
"tied":0,
"pointsFor":82,
"pointsAgainst":62,
"pointsDifference":20
}]
get rows () {
return this.standingsAFCEast.map(standing => ({
team: standing.team.teamName,
coach: standing.team.coach.coachName,
w: standing.won,
l: standing.lost,
t: standing.tied,
fa: standing.pointsFor,
agst: standing.pointsAgainst,
diff: standing.pointsDifference
}))
}
// columns = [{name:'team'}, {name:'coach'}, {name:'w'}, {name:'l'}, {name:'t'}, {name:'fa'}, {name:'agst'}, {name:'diff'}]
columns = Object.keys(this.rows[0]).map(val => ({name: val}))
}
Let me know if this helps!