I'm having a slight issue here when i try to iterate through the data array from "history" ref
As we see here, there is 2 console log, 1 from the request and 1 after we put the data in history both show 2 array which is what the values should be but there is nothing on the table and yes every row have an unique id in the database
I'm still pretty new to vuejs ^^
Template
<template>
<div class="container">
<h3 v-if="loading"> Loading... </h3>
<table>
<tr>
<th>Title</th>
<th>Shares</th>
<th>Price</th>
</tr>
<tr ref="history" v-for="row in history" :key="row.id" >
<td>{{ row.title }}</td>
<td>{{ row.shares }}</td>
<td>{{ row.price }}</td>
</tr>
</table>
</div>
Script
<script>
import { store } from "../store"
import { onMounted, ref, reactive } from "vue"
import { supabase } from "#/supabase"
export default {
setup () {
const loading = ref(true);
const user = supabase.auth.user();
const history = ref([])
async function getHistory() {
try {
loading.value = true;
let { data, error, status } = await supabase
.from("history")
.select(`id, user_id, title, shares, price`)
.eq("user_id", user.id)
console.log(data)
if (error && status !== 406) throw error
if (data) {
history.value = data
console.log(history.value)
}
} catch (error) {
alert(error.message)
} finally {
loading.value = false
}
}
onMounted(() => {
getHistory()
})
return {
loading,
user,
history,
}
},
data() {
return {}
}
}
The issue is using ref="history" on the tr tag, as it will bind the ref with the DOM element, you need to remove it.
<tr v-for="row in history" :key="row.id" >
<td>{{ row.title }}</td>
<td>{{ row.shares }}</td>
<td>{{ row.price }}</td>
</tr>
Related
Version: Vue CLI 2.6.x
I am trying to resolve two issues:
Issue 1:
My Vue app has subscribed to updates via a websocket. I am getting the data continuously and need to keep the table updated with the received data. However the table remains empty even when the list (aqiDataList) has content in it.
Issue 2:
I also need to pass the aqiDataList to the AQITableComponent (where the actual table was originally suppose to be) but having this same issue
App.vue
<template>
<v-container>
<AQITableComponent :aqiList="aqiDataList" />
<v-simple-table>
<template v-slot:default>
<thead>
<tr>
<th class="text-left">
Name
</th>
<th class="text-left">
Age
</th>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr
v-for="item in aqiDataList"
:key="item.id"
>
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
<td>{{ item.location }}</td>
</tr>
</tbody>
</template>
</v-simple-table>
</v-container>
</template>
<script>
import AQITableComponent from './AQITableComponent';
export default {
name: 'AQIComponent',
components: {
AQITableComponent
},
data: function () {
return {
connection: null,
aqiDataList: []
};
},
mounted() {
},
methods: {
},
created: function () {
console.log("Starting connection to WebSocket Server");
this.connection = new WebSocket("wss://my-websocket.com");
this.connection.onmessage = function (event) {
//console.log(event.data);
let aqiDataString = event.data;
this.aqiDataList = [];
let parsedData = JSON.parse(aqiDataString);
parsedData.forEach((aqiData) => {
this.aqiDataList.push({
... object
});
});
console.log(this.aqiDataList);
};
this.connection.onopen = function (event) {
console.log(event);
console.log("Successfully connected to the echo websocket server...");
};
},
}
</script>
AQITableComponent.vue
<template>
<v-container>
<v-simple-table>
<template v-slot:default>
.. same table as shown above
</template>
</v-simple-table>
</v-container>
</template>
<script>
export default {
name: 'AQITableComponent',
props: ['aqiList'],
data: function () {
},
}
</script>
(1) Try using the arrow function for the onmessage event:
from: this.connection.onmessage = function (event) {...}
to: this.connection.onmessage = (event) => {...}
or: this.connection.addEventListener("message", (event) => {...});
This way the this.aqiDataList will be available on your component. Inside the event callback.
This should also solve the problem (2) since your array is not being updated on the first place.
how to render a table after an update delete or insert action here I have a table using the following code
<tbody>
<tr v-for="(item, index) in DATASKILL" :key="item.ID">
<td>{{ index + 1 }}</td>
<td>{{ item.skills }}</td>
<td>{{ item.profiency }}</td>
<td class="text-xs-center">
</tr>
</tbody>
export default {
data: function() {
return {
item: {
skills: "",
profiency: "",
idusers : parseInt(localStorage.getItem("userId")),
},
};
},
computed: {
DATASKILL() {
return this.$store.state.skill //call json using axios in store
},
},
methods:{
Submited() {
this.$store
.dispatch("createSkills", this.item)
.then((response) => {
// setTimeout(()=>{
// this.$store.dispatch('getSkill') // load response json use action get in store
// },2000)
})
.catch((error) => {
error;
});
},
}
when I insert data using the modal form, how do I make the table render without being refreshed?
Can any one assist with why i cant get my array into the following please
HTML:
<table class="table table-hover">
<thead>
<tr>
<td>ID</td>
<td>Email</td>
<td>Password</td>
</tr>
</thead>
<tbody>
<tr v-if="email" v-for="mail in email" :key="">
<td>{{ allMyUsers.id }}</td>
<td>{{ allMyUsers.name }}</td>
<td>{{ allMyUsers.email }}</td>
<td></td>
</tr>
</tbody>
</table>
I'm calling my results as follows, i can see that the array is passed through my log (I think) but really strugging to understand my problem
Script:
import axios from 'axios';
export default {
computed: {
allMyUsers () {
return !this.$store.getters.alluser ? false : this.$store.getters.alluser
},
},
created () {
this.$store.dispatch('allUsers')
}
}
My code for getting the data is as follows and definately returns the data as I can see it in the log, just not sure if im passing it out
allUsers ({commit, state}) {
if (!state.idToken) {
return
}
globalAxios.get('/users.json')
.then(res => {
const data = res.data
const allUsers = []
for (let key in data) {
const user = data[key]
user.id = key
allUsers.push(user)
}
commit('storeUser', allUsers)
})
.catch(error => console.log(error))
}
My getter is as follows
getters: {
alluser (state) {
return state.allUsers
},
}
})
Any support very much appreciated as im new to vue so very much still learning
Many thanks for the help so far, I have tried to follow your guidance but nothing is returned and i now have no errors
my updated code is as follows, I was sure I d followed the guidance you kindly provided
HTML:
<tr v-if="myuser" v-for="myuser in allMyUsers" :key="">
<td>{{ myuser.email }}</td>
<td></td>
</tr>
SCRIPT:
<script>
import axios from 'axios';
export default {
computed: {
allMyUsers () {
return !this.$store.getters.myuser ? false : this.$store.getters.myuser
},
},
created () {
this.$store.dispatch('allMyUsers')
}
}
</script>
GETTER:
myuser (state) {
return state.myuser
},
Function:
allMyUsers ({commit, state}) {
if (!state.idToken) {
return
}
globalAxios.get('/users.json' + '?auth=' + state.idToken)
.then(res => {
const data = res.data
const myusers = []
for (let key in data) {
const myuser = data[key]
myuser.id = key
myusers.push(myuser)
}
commit('storemyuser', myusers)
})
.catch(error => console.log(error))
}
And finally my MUTATION:
storemyuser (state, myuser) {
state.myuser = myuser
},
Thankyou again for your assistance, you guys really are great at helping newbes like me learn
Your v-for loop is not good, email property is not defined in your component, you only defined a computed allUsers property (with getters from your store). It's this one you need to use :
<tr v-if="user" v-for="user in allUsers" :key="">
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td></td>
</tr>
Every 10 seconds I query my database for latest fire calls. I do app.events = data.calls but my data doesn't refresh. I initialize the data with the same function that is called every 10 seconds. I see the table. How I do I replace an array in Vue with an array?
<html>
<head>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script src="https://unpkg.com/vue"></script>
<script>
$(function() {
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
$('#demo').text("Geolocation is not supported by this browser.");
}
}
function showPosition(position) {
$.get('http://localhost:8000/api/nearest_events?lng='+position.coords.longitude+'&lat='+position.coords.latitude, function(data) {
//app.$set(app.events, Object.assign({}, app.events, data.calls));
app.events = data.calls;
})
}
app = new Vue({
el: '#app',
data: {
events: []
},
created: function() {
setInterval(getLocation(), 10000)
}
})
})
</script>
<style>
td, th {border:1px solid #000;padding:5px}
table { border-collapse:collapse;}
</style>
</head>
<body>
<div id="app">
<table>
<tr v-for="event in events">
<td>{{ event.datetime }}</td>
<td>{{ event.address }}</td>
<td>{{ event.type }}</td>
<td>
<table>
<tr><th>Unit</th><th>Dispatched at</th><th>Arrived at</th><th>In service</th></tr>
<tr v-for="unit in event.units">
<td>{{ unit.unit }}</td>
<td>{{ unit.dispatched }}</td>
<td>{{ unit.arrived }}</td>
<td>{{ unit.in_service }}</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</body>
</html>
It appears that your problem is in setInterval. When you call getLocation it does not require the ()
i = 0;
app = new Vue({
el: '#app',
data: {
events: []
},
methods: {
getLocation: function () {
var self = this;
i+=1;
self.events = [1,2,3,i];
}
},
created: function() {
self = this;
setInterval(self.getLocation, 1000);
}
})
And here is a working demo:
https://codepen.io/egerrard/pen/EwLVNB
This is strange because it was just working last night, but basically I have a Vue app that's pulling JSON from my backend. Code below. The strange part is that while the loadData function is running and I see the 'Loaded Data' message in console along with the list of items from the JSON, I then get a console error saying 'items is not defined'. I must have made a subtle typo or some dumb change but I can't find it anywhere!! Any ideas?
HTML snippet:
<div id="app">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Query</th>
<th>Initiated By</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<div v-for="item in items">
<td>{{ item.id }}</td>
<td>{{ item.query }}</td>
<td>{{ item.user }}</td>
<td>{{ item.type }}</td>
</div>
</tr>
</tbody>
</table>
</div>
</div>
(And then <script src="app.js"></script> right before </body>)
JS code:
new Vue({
el: '#app',
data: {
items: [],
interval: null
},
methods: {
loadData: function () {
$.get('http://localhost:4567/getQueue', function (response) {
this.items = response.results;
console.log("Loaded data.")
console.log(response.results)
}.bind(this));
}
},
created: function () {
console.log("Loading data...")
this.loadData();
console.log(items)
this.interval = setInterval(function () {
this.loadData();
}.bind(this), 3000);
},
beforeDestroy: function(){
clearInterval(this.interval);
}
});
You are getting the error
items is not defined
because of following line:
created: function () {
console.log("Loading data...")
this.loadData();
console.log(items) <== this should be console.log(this.items)
Turns out there was a few issues in my code.
1) As was pointed out by Saurabh, I forgot to put this.items instead of items.
2) this can't be referenced inside of the function I defined as I have it... instead, the function has to be defined with =>, for example:
$.get('http://localhost:4567/getQueue').then((response) => {
this.items = response.data.results;
console.log("loadData finished - items length is: "+this.items.length)
})
3) The big error I had was that my div bind with items was inside the table tag, which apparently isn't okay to do. Instead I applied the Vue binds to the existing tags (table, tr).