I have a reusable component that is a video.js video player. This component works fine when the data is passed in on the initial DOM load.
I need to figure out why my component is not re-rendering after the state is updated in Vuex.
The parent component passes down the data for the video via props. I also have this set to be used with multiple videos and it works fine with a single one or many.
<div v-for="video in videos" :key="video.id">
<video-player :videoName="video.videoName" :videoURL="video.videoURL" :thumbnail="video.thumbnail"></video-player>
</div>
I'm setting the initial state to a generic video for all users in my Vuex store.
getFreeVideo: [
{
videoName: "the_video_name",
videoURL: "https://demo-video-url.mp4",
thumbnail: "https://s3.amazonaws.com/../demo-video-poster.jpg"
}
]
This is set in data in videos
(and later set to getFreeVideo)
data () {
return {
videos: []
}
}
I'm setting videos
in data() to getFreeVideo in the store within the created() lifecycle:
this.videos = this.getFreeVideo
..and checking if a user has a personal video and updating the state in the created() lifecycle.
this.$store.dispatch('getFreeVideo', 'the_video_name')
This makes a request with axios and returns our video data successfully.
I'm using mapState import { mapState } from 'vuex
to watch for a state change.
computed: {
...mapState(['getFreeVideo'])
}
I am not seeing why this.videos
is not being updated.
Here, my assumption regarding the expected behaviour would be videos[]
being updated from the state change and a re-rendering of the component.
As you can see below, the state has been updated, and the videoUpdate()
within the computed properties has the new data as well:
..but,
videos[]
is never updated thus the video component never gets the props new props etc..
A couple of notes:
- already tried, hiding the child component with
v-if
(and showing after state change) - tried
setTimeout
to test things, but the data will come through and then the videoJS player never instantiates correctly (must have initial data) - tried doing this with a local method / not using Vuex state
- console is showing error
TypeError: Cannot read property '_withTask' of undefined
but this happens even when the demo video loads correctly, so this seem unrelated, and I can't find anything anywhere in here that presents itself as undefined.
TL;DR
I basically can't get child component to re-render after the state change.
And although I can get the data into videos[]
with a different structure, it still never re-renders.
Why is the data not making it through, and the re-render never happening?
Please don't post answers that only contain links to 'understanding reactivity' or something without any explanation.
appended for @acdcjunior
//action
getFreeVideo: (context, videoName) => {
axios({
method: 'post',
url: 'https://hidden-for-posting',
data: {
action: 'getVideo',
userId: '1777', // (hardcoded to test)
videoName: videoName
},
headers: {
'x-api-key': apiKey,
'Content-Type': 'application/json'
}
})
.then(response => {
let video = [
{
videoName: response.data.videoName,
videoURL: response.data.videoURLs.mp4,
thumbnail: response.data.thumbnails['1280']
}
]
return context.commit('updateGetFreeVideo', video)
})
.catch(error => {
if (error.response) {
console.log(error.response)
} else if (error.request) {
console.log(error.request)
} else {
console.log('Error', error.message)
}
console.log(error.config)
})
}
// mutation:
updateGetFreeVideo: (state, payload) => {
return state.getFreeVideo = payload
}
// getter:
getFreeVideo: state => {
return state.getFreeVideo
}