1

I have a small django project and frontend is coded with Vue.js via CDN. So it has only one server for django. And vue is placed into django templates.

DRF is the source of web apis.

Django 2.2.10, DRF 3.11.0 and vue gets the latest from CDN.

Vuetify (again from CDN) gives material UI design with v-app-bar, v-navigation-drawer and v-footer.

Also Vuetify's v-data-table is used for two datasets. (countries and their cities)

I can show the data when the page first responded.

HOWEVER, when the drawer is closed with a button click or when the 'rows per page' of v-data-table has changed, data disappears. I should refresh the page to get it back.

error is:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "tableData"

found in

---> <LocCountry>
       <VContent>
         <VApp>
           <Root>

list page:

{% extends 'locations/index.html' %} {% load static%} {% block content %}
<loc-country></loc-country>
{% endblock %}{% block extrascript %}
<script>
  Vue.component("loc-country", {
    props: ["tableData"],
    template: `
      <v-data-table
        :headers="headers"
        :items="tableData"
        class="elevation-1"></v-data-table>
    `,
    data() {
      return {
        // tableData: null,
        loading: true,
        errored: false,
        headers: [
          { text: "Country", value: "name" },
          { text: "ISO-2", value: "iso2" }
        ]
      };
    },
    created() {
      axios
        .get("/api/country/")
        .then(res => (this.tableData = res.data.results))
        .catch(error => {
          console.log(error);
          this.errored = true;
        })
        .finally(() => (this.loading = false));
    }
  });
</script>
{% endblock %}

and you can find the repo of the project here with data included if you loaddata: https://github.com/pydatageek/locations

Py Data Geek
  • 43
  • 2
  • 5

2 Answers2

1

Quick fix is to use new variable in data with same data from tableData.

Try like this:

Vue.component("loc-country", {
    props: ["tableData"],
    template: `
      <v-data-table
        :headers="headers"
        :items="newTableData"
        class="elevation-1"></v-data-table>
    `,
    data() {
      return {
        newTableData: this.tableData.slice()
      };
    },
    created() {
      axios
        .get("/api/country/")
        .then(res => (this.newTableData = res.data.results))
    }
  });

This should work.

More about that you can find here.

mare96
  • 3,035
  • 1
  • 9
  • 21
  • thank you, but another error appeared after that: Uncaught SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse () – Py Data Geek Mar 03 '20 at 23:09
  • 1
    Ok, you can check also how to clone array [here](https://stackoverflow.com/questions/3978492/fastest-way-to-duplicate-an-array-in-javascript-slice-vs-for-loop). I updated my answer @PyDataGeek – mare96 Mar 03 '20 at 23:15
  • slice() didn't work either. errors are: Error in data(): "TypeError: Cannot read property 'slice' of undefined" and etc. I think, it is about returning an empty array. Would it be problem if you play with the repo? It will last max 3-4 min to clone and load the dummy data. Thank you again. – Py Data Geek Mar 04 '20 at 00:52
  • 1
    It is solved and I wrote the solution below. Thank you for your help. @mare96 – Py Data Geek Mar 05 '20 at 14:36
0

I couldn't find it anywhere, but the solution of this issue was so easy. Don't use tableData as a prop, but put it in data property and don't initiate it as null. It should be an empty array.

Change the list page as below:

...
// props: ["tableData"],
....
tableData: []
...

P.S: I do not know the reason! WHY is that SO?

Py Data Geek
  • 43
  • 2
  • 5