0

I have the following setup on my project:

window.school = {
    "id": 1,
    "users": [
        {
            "id": 0,
            "name": "Adam Carter",
            "work": "Unilogic",
            "email": "adam.carter@unilogic.com",
            "dob": "1978",
            "address": "83 Warner Street",
            "city": "Boston",
            "optedin": true
        },
        {
            "id": 1,
            "name": "Leanne Brier",
            "work": "Connic",
            "email": "leanne.brier@connic.org",
            "dob": "13/05/1987",
            "address": "9 Coleman Avenue",
            "city": "Toronto",
            "optedin": false
        }
    ],
    "images": [
        "img0.png",
        "img1.png",
        "img2.png"
    ],
    "coordinates": {
        "x": 35.12,
        "y": -21.49
    },
    "price": "$59,395"
}
const app = new Vue({
    router,
    el: '#app',
    data: {
        school: school,
    }
});

And one of my vue components is as School.vue

<template>
    <div>
        <input type="button" value="Update school data" v-on:click="update()">
    </div>
</template>

<script>
    export default {
        props:[
            'school',
        ],
        methods: {
            update: function() {
                let url = `/api/v1/school/${this.school.id}/update`;
                this.axios.get(url, this.decisions)
                  .then((res) => {
                      // WARNING IS THROWN IN HERE
                      this.school = res.data.school;
                  })
                  .catch((error) => {
                      console.log(error);
                  });
            }
        },
    }
</script>

But I get the following warning: warning: Avoid mutating a prop directly

So the question is, how can I update the app "school" information from a Vue Component? I'm not very familiar with Vue and I don't know if I'm following an antipattern or something else, thanks a lot for your help.

JohnnyAce
  • 3,569
  • 9
  • 37
  • 59

1 Answers1

0

In parent-child relation the data flows only from parent to child through props. So, you can't directly change parent data from child. You must just emit particular event for which you let the parent listen.


In parent context where you using component School, use it with additional directive:

<div id="app">
  <school v-on:update="updateSchool"></school>
</div>

Add particular method to parent:

const app = new Vue({
  router,
  el: '#app',
  data: {
    school: school,
  },
  methods: {
    updateSchool (data) {
      this.school = data
    }
  }
})

And edit School.vue script:

<script>
  export default {
    props:[
      'school',
    ],
    methods: {
      update: function() {
        let url = `/api/v1/school/${this.school.id}/update`;
        this.axios.get(url, this.decisions)
          .then((res) => {
            this.$emit('update', res.data.school);
          })
          .catch((error) => {
            console.log(error);
          });
      }
    },
  }
</script>