1

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">&#128077; 47</div>
                    <div class="selected__dislike">&#128078; 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>
1

1 Answer 1

1

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);
            }
        }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.