Kaloyan Nikolov
Kaloyan Nikolov

Reputation: 111

How can I force the nested component to rerender

Hello so these are my two objects

TaskTable object which contains the columns

 <template>
        <ul class="tasks-columns" id="tasks-columns">

            <li class="col-sm-4 col-lg-2 task-column-wrapper list-unstyled" v-for="status in statuses" :id="status">
                <draggable :emptyInsertThreshold="10" @add="endDrag" ghost-class="ghost" group="tasks">
                        <task v-for="task in tasks[status]" :task="task" :key="task.id"></task>
                </draggable>
            </li>

        </ul>
</template>

<script>
import draggable from 'vuedraggable'

export default {
    data: function () {
        return {
            statuses: [],
            users: [],
            tasks: []
        }
    },
    components: {
        draggable
    },
    mounted() {
        this.loadStatuses();
        this.loadTasks();
        this.loadUsers();
    },
    methods: {
        loadStatuses: function () {
            axios.get('/api/tasks/get-statuses')
                .then((response) => {
                    this.statuses = response.data;
                })
                .catch(function (error) {
                    console.log(error);
                });
        },
        loadUsers: function () {
            axios.get('/api/users')
                .then((response) => {
                    this.users = response.data.data;
                })
                .catch(function (error) {
                    console.log(error);
                });
        },

        loadTasks: function () {
            axios.get('/api/tasks/tasks-for-table')
                .then((response) => {
                    this.tasks = response.data;
                })
                .catch(function (error) {
                    console.log(error);
                });
        },
        endDrag: function (event) {
            let column = event.to.parentElement.parentElement
            $.ajax({
                url: '/tasks/change-status',
                type: 'POST',
                data: {'task_id': event.item.id, 'status': column.id},
                success: function (data) {
                    if (data.success) {
                        Toastify({
                            text: "Task status has been successfully updated!",
                            duration: 3000,
                            destination: base_url + '/tasks' + "show/" +  event.item.id,
                            newWindow: true,
                            close: true,
                            className: 'custom-toast',
                            gravity: "top", // `top` or `bottom`
                            position: "center", // `left`, `center` or `right`
                            backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
                            stopOnFocus: true, // Prevents dismissing of toast on hover
                            onClick: function () {
                            } // Callback after click
                        }).showToast();

                    }
                }
            });
        }


    }
}
</script>

And the Task object which represents each Cell of the columns

<template>


                <div class="task-wrapper" style="padding: 10%" :id="task.id">
                    <div class="task" >
                        <section style="margin-bottom: 1rem;">
                            <label>
                                {{ task.title }}
                            </label>
                        </section>
                        <section style="margin-bottom: 0.5rem;" class="task-table-task-status">
                                    <span style="padding-right: 5px;" data-toggle="tooltip" data-placement="right"
                                          title="Status">
                                        {{ task.status }}
                                    </span>
                        </section>
                        <section>
                    <span style="padding-right: 5px;" data-toggle="tooltip" data-placement="right"
                          title="Estimate">{{ task.estimate }}</span>

                            <div v-if="task.id" class="float-right">
                                <a class="c-header-nav-link" data-toggle="tooltip" data-placement="bottom"
                                   title="Assignee">
                                    <div class="c-avatar" style="width: 25px; height: 25px">
                                        <img class="c-avatar-img" :src="'/uploads/avatars/'+task.user.avatar">
                                    </div>
                                </a>
                            </div>
                        </section>
                    </div>
                </div>

</template>

<script>

export default {
    props: ['task'],
    data: function () {
        return {}
    },
    components: {
        draggable
    },
    mounted() {
        this.loadTask();
    },
    methods: {
        loadTask: function () {

        },
        reloadTask: function () {
            console.log('test');
        }

    }
}
</script>

So currently they are draggable and the drag between columns is calling an endpoint which updates the task status, however in the UI the task status is the old one, I want to force update the Task object which was moved. Any idea how to do that ?

Upvotes: 0

Views: 464

Answers (1)

Guru
Guru

Reputation: 169

You had not any updates on front-end part (inside vue) You need to do something like this:

endDrag: function (event) {
        let column = event.to.parentElement.parentElement
        $.ajax({
            url: '/tasks/change-status',
            type: 'POST',
            data: {'task_id': event.item.id, 'status': column.id},
            success: function (data) {
                if (data.success) {

                    const task = this.tasks.find(t => t.id === event.item.id);
                    task.status = column.id;

                    Toastify({
                        text: "Task status has been successfully updated!",
                        duration: 3000,
                        destination: base_url + '/tasks' + "show/" +  event.item.id,
                        newWindow: true,
                        close: true,
                        className: 'custom-toast',
                        gravity: "top", // `top` or `bottom`
                        position: "center", // `left`, `center` or `right`
                        backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
                        stopOnFocus: true, // Prevents dismissing of toast on hover
                        onClick: function () {
                        } // Callback after click
                    }).showToast();

                }
            }
        });
    }

So find the task to update:

const task = this.tasks.find(t => t.id === event.item.id);

And update it with you status

task.status = column.id;

Upvotes: 1

Related Questions