I already read some similar topics about my problem, but still I can’t figure out, what can be the problem is. Long story short, I have an array of objects, and these objects also have an array, called “messages”. The parent object has some additional data, and my problem is caused by the child array, the messages.
The problem is: The messages array is filled up by the server. After it, I successfully render a list of it’s content, show it on the web page, so far so good. But as soon as a new data arrives from the server, the rendered list is not updating itself. I checked the array’s content via the Vue dev plugin, and the new message was there, but the rendered list still remained in it’s original state.
The twist in the story is, that I created a simple test array, which is very similar to the original one, and also rendered on the page. When a new message arrives, I push it to both of them, and to my surprise, each one is updating itself perfectly. For the sake of curiosity, I commented out the test array rendering, and believe it or not, the original array does not update itself anymore on the page. After I remove the commented test array render, both of them works again.
The vue component:
/**
* Root
*/
import Vue from 'vue'
import axios from 'axios'
import inputComponent from './chat/input.vue'
new Vue({
el: '#chat-root',
components: { inputComponent },
data() {
return {
userID: document.getElementById('user').value,
ready: false,
roomID: "",
roomInstances: [],
test: [
{
messages: []
}
],
pollTime: 5000
}
},
created() {
axios.get('chat/init')
.then(resp => {
this.roomID = resp.data.roomList[0]._id
this.roomInstances = resp.data.roomList
this.fetchMessagesFromServer()
this.poll()
this.heartBeat()
}).catch(err => console.log(err))
},
computed: {
getMessages() {
return this.roomInstance.messages
},
roomInstance() {
return this.roomInstances.filter(i => i.id = this.roomID)[0]
}
},
methods: {
setRoom(id) {
if (this.roomID === id)
return
this.roomID = id
},
fetchMessagesFromServer() {
axios.get(`chat/get/${this.roomID}`)
.then(resp => {
this.roomInstance.messages = resp.data.messages
this.ready = true
}).catch(err => console.log(err))
},
heartBeat() {
setInterval(() => axios.get(`heartbeat/${this.userID}`), this.pollTime - 1000)
},
poll() {
axios.create({ timeout: this.pollTime })
.get(`poll/${this.userID}`).then(resp => {
if (resp.data.data) {
this.roomInstance.messages.push(resp.data.data.message)
this.test[0].messages.push(resp.data.data.message)
}
this.poll()
}).catch(err => console.log(err))
}
}
})
Template:
extends base
block scripts
script(src="/dist/chat.bundle.js")
block content
#chat-root(style="margin-top: 50px" v-cloak)
// Hack! Supposed to be an axios request?
input(v-if="false" id="user" value=`${user._id}`)
input-component(:room="roomID")
p {{ roomID || "Whoo hooo hoooo!" }}
span(v-for="room in roomInstances" @click="setRoom(room._id)") {{ room.name }} |
div(v-if="ready")
div(v-for="message in getMessages")
p {{ message }}
hr
div(v-for="fe in test[0].messages")
p {{ fe }}
roomInstance.messagereactive and always addkeytov-forkeywithv-foris really only necessary when usingv-forwith a component tag.