I've built an API that sends a video with all of its comments and in the front end, the video is called on mount. I have a create comment button that calls a createComment route that adds a comment to the video and saves it in the database. However, the new comment does not appear because after the first get all videos fetch is called, the code then uses session storage to keep the videos and not have to call to the API on every mount. Is there any way I could add the new comment to the session storage. All comments are stored within their video so video is an object with a comments array property.
Thank you for any help with this.
HOME PAGE
<template>
<div class="home">
<SelectedVideo v-bind:user="user" v-bind:video="videos[0]"/>
</div>
</template>
<script>
import axios from 'axios';
import SelectedVideo from '../components/SelectedVideo.component';
axios.defaults.withCredentials = true;
export default {
name: 'Home',
components: {
SelectedVideo
},
data() {
return {
videos: [],
user: null
}
},
created() {
if (sessionStorage.homeVideos) {
console.log('Getting from session storage...');
this.videos = JSON.parse(sessionStorage.homeVideos);
} else {
console.log('Getting from API and setting res to session storage...');
axios.get('http://localhost:8000/api/v1/videos')
.then(res => {
sessionStorage.setItem('homeVideos', JSON.stringify(res.data.data.videos));
this.videos = JSON.parse(sessionStorage.homeVideos);
})
.catch(err => console.log("ERROR: " + err.response.data.message));
}
},
mounted(){
if (sessionStorage.user) {
// this.videoId = video._id
this.user = JSON.parse(sessionStorage.user);
}
}
}
</script>
<style lang="scss" scoped>
</style>
Selected Video component
<template>
<div class="selected">
<h2 class="selected__title">{{video.title}}</h2>
<video class="selected__video" :src=video.video controls :poster=video.thumb></video>
<div style="width: 70%;">
<div class="selected__details">
<h3 class="selected__details__views">300 views</h3>
<div class="selected__thumbs">
<div class="selected__like">👍 47</div>
<div class="selected__dislike">👎 3</div>
</div>
</div>
<form class="selected__commentbox">
<label for="comments" class="selected__commentbox__label">Comments</label>
<textarea v-model="text" class="selected__commentbox__textarea" rows="4" id="comments" placeholder="Type a sweet comment..."></textarea>
<button @click="handleSubmit" class="selected__commentBtn">add comment</button>
</form>
<div v-bind:key="comment._id" v-for="comment in video.comments" class="selected__comments">
<Comment v-bind:comment="comment"/>
</div>
</div>
</div>
</template>
<script>
import Comment from './Comment.component.vue';
import axios from 'axios';
export default {
name: 'SelectedVideo',
data() {
return {
text: null,
videoId: this.video._id,
userId: this.user._id
}
},
props: ["video", "user"],
components: {
Comment
},
methods: {
handleSubmit(event) {
event.preventDefault();
this.createComment(this.text, this.videoId, this.userId);
this.text = '';
},
async createComment(comment, video, user) {
try{
const res = await axios({
method: 'POST',
url: 'http://localhost:8000/api/v1/comments/',
data: {
comment,
video,
user
}
});
if (res.data.status === 'success') {
// location.reload(true);
console.log(res);
}
} catch(err) {
console.log(err.response.data.message);
}
}
}
}
</script>
To achieve what you described, I think there some changes need to made in your files beside sessionStorage
logic to make it work. First, you need to add a method so that the SelectedVideo.vue can update the video comments in its parent, which is Homepage
Homepage
<SelectedVideo v-bind:user="user" v-bind:video="videos[0]" @updateComment=updateComment/>
methods: {
updateComment(comments) {
this.$set(this.videos, 0, {...this.videos[0],...comments}); //update Vue video list
sessionStorage.setItem("homeVideos", JSON.stringify(this.videos)); // update sessionStorage for future load
}
}
Second, after getting the new comments, you need to call the parents updateComment
methods so that it can update the videos list
SelectedVideo.vue
async createComment(comment, video, user) {
try{
const res = await axios({
method: 'POST',
url: 'http://localhost:8000/api/v1/comments/',
data: {
comment,
video,
user
}
});
if (res.data.status === 'success') {
this.$emit("updateComment", res.data.data); // call parents update method
console.log(res);
}
} catch(err) {
console.log(err.response.data.message);
}
}