0

I have one file vue component with one property 'todo-item' with such structure

{
  id:1,
  text:'Buy tickets',
  isDone: false,
  person:'Boss',
  location:'Boryspil',
  childTask:null,
},

And I have computed properties:

computed:{ 
  hasLocation(){
      return this.todoItem.location;
  },
  hasPerson(){
      return this.todoItem.person;
  },
  hasChildTask(){
      return this.todoItem.childTask;
  },
  hasParentTask(){
      return true;
  },
}

And I want to make all of object properties reactive, but when I change properties in method:

deletePerson(){
  this.$set(this.todoItem, 'person', null);
  console.log(this.hasPerson);
  console.log(this.todoItem.person);
},

todoItem.person is still not reactive, this.hasPerson have old value, and this.todoItemPerson shows null value. I tried to make them reactive on created method, but it's still not reactive.

This is by component whole js code, without template and css for short:

    <script>
    import HoveredChip from "@/components/HoveredChip";
    import {mapMutations} from 'vuex';
    export default {
        name: "TodoItem",
        components: {HoveredChip},
        props:['todo-item'],
        data() {
            return{
                isActive : true,
            }
        },
        computed:{

            hasLocation(){
                return this.todoItem.location;
            },
            hasPerson(){
                return this.todoItem.person;
            },
            hasChildTask(){
                return this.todoItem.childTask;
            },
            hasParentTask(){
                return true;
            },
            people(){
                return [
                    "dad",
                    "Ann",
                    "boss",
                    "prostitute"
                ]
            },
            places(){
                return []
            }
        },
        methods:{
            ...mapMutations(['addPersonMutation'],{

            }),
            moveToPerson(){

            },
            moveToLocation(){

            },
            moveToPatentTask(){

            },
            addLocation(){

            },
            addPerson(val){
                this.addPersonMutation(val);
                this.$set(this.todoItem,'person',val);
                console.log(this.hasPerson);
                console.log(this.todoItem.person);
            },

            addChildTask(){

            },
            deletePerson(){
                this.$set(this.todoItem, 'person', null);
                console.log(this.hasPerson);
                console.log(this.todoItem.person);
            },
            deleteLocation(){

            },
            deleteChildTask(){

            },
            editLocation(){

            },
            savePerson(){

            },
            editChildTask(){

            }

        },
        created(){
            // this.$set(this.todoItem, 'person', 'undefined');
            // this.$set(this.todoItem, 'location', '????');
            // this.$set(this.todoItem, 'isDone', "....");
        }
    }
</script>
3
  • are you passing todo-items from parent? Commented Dec 24, 2020 at 16:47
  • Yes same question as @kasvith, is the data obect a prop or data? Commented Dec 24, 2020 at 18:11
  • Yes, I pass todo-item as property from parent element, and I think it is the main problem, I must do it reactive in parent element, or replace the whole object in parent element while I update some property, anyway it must be sended to server and replaced in future, so I think I will try this way and in case of adding new todo-item I will work with data object. Commented Dec 25, 2020 at 18:41

2 Answers 2

4

The issue is with your property name. Change the 'todo-item' in the data section to todoItem.

This works

<template>
    <div>
        <button @click.prevent="printPerson">Print Person</button>
        <br />
        <button @click.prevent="deletePerson">Delete Person</button>
    </div>
</template>

<script>
    export default {
        data: () => ({
            todoItem: {
                id: 1,
                text: 'Buy tickets',
                isDone: false,
                person: 'Boss',
                location: 'Boryspil',
                childTask: null,
            },

        }),
        computed: {
            hasLocation() {
                return this.todoItem.location;
            },
            hasPerson() {
                return this.todoItem.person;
            },
            hasChildTask() {
                return this.todoItem.childTask;
            },
            hasParentTask() {
                return true;
            },
        },

        methods: {
            deletePerson() {
                this.$set(this.todoItem, 'person', null);
                // this.todoItem.person = "null"
                console.log(this.hasPerson);
                console.log(this.todoItem.person);
            },
            printPerson() {
                console.log(this.hasPerson);
                console.log(this.todoItem.person);
            }
        }
    }
</script>

Also, using "this.todoItem.person = null" works.

If still doesn't work for you, edit your question and add the complete component code and we can help.

Sign up to request clarification or add additional context in comments.

Comments

0

My problem was in props, I get todoItem from parent element, and I can't do it reactive, but with deep watch all object properties becomes reactive. I solved my problem just adding watch property to my component:

And now when I change person (or any other) property of my todoItem changes updates in computed properties either.

    watch:{
        todoItem:{
            deep: true,
            handler(){
                this.saveTodoAction(this.todoItem);
            }
        }
    },

And this is the whole code:

import HoveredChip from "@/components/HoveredChip";
import {mapMutations, mapActions} from 'vuex';
export default {
    name: "TodoItem",
    components: {HoveredChip},
    props:['todo-item'],
    data() {
        return{
            isActive : true,
        }
    },
    computed:{

        hasLocation(){
            return this.todoItem.location;
        },
        hasPerson(){
            return this.todoItem.person;
        },
        hasChildTask(){
            return this.todoItem.childTask;
        },
        hasParentTask(){
            return true;
        },
        people(){
            return [
                "Dad",
                "Ann",
                "Boss",
                "Prostitute"
            ]
        },
        places(){
            return []
        }
    },
    methods:{
        ...mapMutations(['addPersonMutation'],{

        }),
        ...mapActions(['saveTodoAction']),
        moveToPerson(){

        },
        moveToLocation(){

        },
        moveToPatentTask(){

        },
        addLocation(){

        },
        addPerson(val){
            this.addPersonMutation(val);
        },

        addChildTask(){

        },
        deletePerson(){
            this.todoItem.person = null;
        },
        deleteLocation(){

        },
        deleteChildTask(){

        },
        editLocation(){

        },
        savePerson(){

        },
        editChildTask(){

        },

    },
    watch:{
        todoItem:{
            deep: true,
            handler(){
                this.saveTodoAction(this.todoItem);
            }
        }
    },
    created(){
    }
}

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.