Do not directly change a prop - VueJS Datatable

Just starting out on Vue JS and encountered an issue while trying to create a Data Table by passing parent props to child components.

An Error Occurred:

[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: "editedItem"


Below is the code snippet for reference:

This is my Page :

<template >
  <v-container  >

    <v-col>
     <Datatables
      :headers="this.headers"
      :items="items"
      :editedItem="this.editedItem"
      :defaultItem="defaultItem"
      sort-by="calories"
      class="elevation-1" />
    </v-col>
  <v-spacer></v-spacer>
  <br>
    <v-col>

    </v-col>
  </v-container >
</template>

<script>

import Datatables from '../../components/Datatable/CrudDatatable'
export default {

  components:{

    Datatables

  },
  data() {
   return {

      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          sortable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Actions', value: 'action', sortable: false },
      ],
      items: [],
      editedItem: {
        name: '',
        calories: 0,
        fat: 0,
        carbs: 0,
        protein: 0,
      },
      defaultItem: {
        name: '',
        calories: 0,
        fat: 0,
        carbs: 0,
        protein: 0,
      },


   }
 },
  created () {
      this.initialize()
    },
    methods: {
       initialize () {
        this.items = [
          {
            name: 'Frozen Yogurt',
            calories: 159,
            fat: 6.0,
            carbs: 24,
            protein: 4.0,
          },
          {
            name: 'Ice cream sandwich',
            calories: 237,
            fat: 9.0,
            carbs: 37,
            protein: 4.3,
          },
        ]
      },



    },


}



</script>


<style>

</style>


This is my Component :

<template>
  <v-data-table :headers="headers" :items="items" sort-by="calories" class="elevation-1">
    <template v-slot:top>
      <v-toolbar flat color="white">
        <v-toolbar-title>My CRUD</v-toolbar-title>
        <v-divider class="mx-4" inset vertical></v-divider>
        <v-spacer></v-spacer>
        <v-dialog v-model="dialog" max-width="500px">
          <template v-slot:activator="{ on }">
            <v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn>
          </template>
          <v-card>
            <v-card-title>
              <span class="headline">{{ formTitle }}</span>
            </v-card-title>

            <v-card-text>
              <v-container>
                <v-row>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.name" label="Dessert name"></v-text-field>
                  </v-col>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.calories" label="Calories"></v-text-field>
                  </v-col>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.fat" label="Fat (g)"></v-text-field>
                  </v-col>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.carbs" label="Carbs (g)"></v-text-field>
                  </v-col>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.protein" label="Protein (g)"></v-text-field>
                  </v-col>
                </v-row>
              </v-container>
            </v-card-text>

            <v-card-actions>
              <v-spacer></v-spacer>
              <v-btn color="blue darken-1" text @click="close">Cancel</v-btn>
              <v-btn color="blue darken-1" text @click="save">Save</v-btn>
            </v-card-actions>
          </v-card>
        </v-dialog>
      </v-toolbar>
    </template>
    <template v-slot:item.action="{ item }">
      <v-icon small class="mr-2" @click="editItem(item)">mdi-pencil</v-icon>
      <v-icon small @click="deleteItem(item)">mdi-delete</v-icon>
    </template>
    <template v-slot:no-data>
      <v-btn color="primary" @click="initialize">Reset</v-btn>
    </template>
  </v-data-table>
</template>
<script>
export default {
  props: {
    headers: {
      type: Array
    },
    items: {
      type: Array
    },
    editedItem: {
      type: Object
    },
    defaultItem: {
      type: Object
    }
  },
  data: () => ({
    dialog: false,
    editedIndex: -1,
  }),

  computed: {
    formTitle() {
      return this.editedIndex === -1 ? "New Item" : "Edit Item";
    }
  },

  watch: {
    dialog(val) {
      val || this.close();
    }
  },
  created () {
      this.getParentItem()
    },
  methods: {

    getParentItem(){



    },

    editItem(item) {
      this.editedIndex = this.items.indexOf(item);
      this.editedItem = Object.assign({}, item);
      this.dialog = true;
    },

    deleteItem(item) {
      const index = this.items.indexOf(item);
      confirm("Are you sure you want to delete this item?") &&
        this.items.splice(index, 1);
    },

    close() {
      this.dialog = false;
      setTimeout(() => {
        this.editedItem = Object.assign({}, this.defaultItem);
        this.editedIndex = -1;
      }, 300);
    },

    save() {
      if (this.editedIndex > -1) {
        Object.assign(this.items[this.editedIndex], this.editedItem);
      } else {
        this.items.push(this.editedItem);
      }
      this.close();
    }
  }
};
</script>



Answer №1

To enhance the functionality of your component, consider adding data variables in the created hook that are initially set to the prop variables:

this.internalItems = this.items;
this.internalEditedItem = this.editedItem;

Subsequently, within your methods, manipulate these internal variables rather than directly altering the prop variables.

this.internalEditedItem = Object.assign({}, item);
...
Object.assign(this.items[this.editedIndex], this.internalEditedItem);
...and so on

If there's a possibility of the parent component modifying the props, it is advisable to implement a watcher for these variables to ensure they reflect the updated values.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The validation for Australian mobile numbers should include the option to have spaces between the digits

How can I validate a mobile number properly? The first text input should start with 04 It should have a total of 10 digits, including 04 (e.g. 0412345678) Below is my input field: <form name="uploadForm"> <input type="tel" name="MobileNumber" ...

Use Entity Objects instead of Strings in your Ajax requests for improved data handling

As I work on developing a web portal with Freemarker(FTL) as the front end technology, my project revolves around a single FTL page that utilizes a wizard to manage various user requests. The back end is structured using the Spring MVC pattern, where contr ...

Need help tackling this issue: getting the error message "Route.post() is asking for a callback function, but received [object Undefined]

I am currently working on implementing a new contactUs page in my project that includes a form to store data in a mongoDB collection. However, after setting up all the controller and route files and launching the app, I encountered an error that I'm u ...

What are the steps to creating a duplicate of JotForm?

After exploring JotForm, I discovered it is an extremely interactive form builder utilizing the Prototype JS library. I am curious to know which JS framework or library would be a solid foundation for creating a similar form builder - JQuery, Prototype, ...

Refreshing a web page in Internet Explorer can cause the HTTP Header content to be altered

As I monitor my dashboard retrieving continuous data from an SAP server, I stumbled upon a solution to fetch the current server date. This approach allows me to display when the dashboard was last updated, and this date is displayed in the DOM. //Method f ...

challenges encountered when saving a getjson request as a variable

I am experiencing difficulties in retrieving a variable from a getJSON() request. The issue lies within the following three functions: function getPcLatitude() { // onchange var funcid = "get_postcode_latitude"; var postcode = parseInt($('#i ...

Trouble arises with Pagination feature of Mui Data Table

Currently, I am working on a project that involves retrieving data from the CoinMarketCap API and presenting it in an MUI Data Table (specifically a StickyHeader Data Table). However, I have been encountering difficulties with changing the color of the tex ...

What is the proper way to utilize --legacy-peer-deps or enforce in a vite build?

I encountered an issue with a package called react-typed in my project. To install it, I had to use --legacy-peer-deps. When deploying, I need to use vite build. However, when I run the command, I receive the following errors: 8:59:31 AM: npm ERR! node_mo ...

Using Javascript to create bold text within a string

I have noticed that many people are asking about this issue, but it seems like a clear and simple answer is hard to come by. Currently, I am working with Vue and trying to display text from an object in a component. My goal is to highlight the price port ...

Running two different versions of the same React-App concurrently: A step-by-step guide

I currently have a react-app that was created using create react app. There is an older branch that is approximately 1 month old, as well as a current branch. I am interested in running both branches simultaneously and making changes to the current branch ...

The parameter did not successfully transfer to the internal function within Firebase Cloud Functions

I am currently working on a Firebase cloud function that looks like this: exports.foo = functions.database .ref("/candidates/{jobTrack}/{candidateId}") .onCreate((snap, context) => { const candidate = snap.val().candidate; const jobTrack = ...

Interacting with an iframe element using Selenium in Python

I have a webpage with an iframe embedded, and I'm using Selenium for test automation: <iframe class="wysihtml5-sandbox" security="restricted" allowtransparency="true" frameborder="0" width="0" height="0" marginwidth="0" marginheight="0" style="dis ...

Implementing line breaks in JSON responses in an MVC application

I am looking to show a JavaScript alert with line breaks using the message returned from a controller action that returns JSON result. I have included "\n" in the message for line breaks. Below is the code snippet from my controller: [HttpPost] publ ...

Using the Spread Operator to modify a property within an array results in an object being returned instead of

I am trying to modify the property of an object similar to this, which is a simplified version with only a few properties: state = { pivotComuns: [ { id: 1, enabled : true }, { id: 2, enabled : true ...

Intellij IDEA does not offer auto-completion for TypeScript .d.ts definitions when a function with a callback parameter is used

I've been working on setting up .d.ts definitions for a JavaScript project in order to enable auto-completion in Intellij IDEA. Here is an example of the JavaScript code I'm currently defining: var testObj = { tests: function (it) { ...

Regular expression to match a string with a minimum of 10 characters, including at least 3 digits and alphanumeric

I need assistance creating a regular expression that validates strings with a minimum of 10 alphanumeric characters and at least 3 digits. For example: X6JV2YUW8T => True JN1H86LEKA => True 111JEJE134 => True A111111111 => True ABCDEFGHIJ =&g ...

the specified computed property does not have a value assigned

Issue with the Computed name Property in a Component <template> <div class="person"> <p>{{name}}</p> </div> </template> <script> export default { name: 'person', data () { return ...

Resolving issues with jQuery's live() method while incorporating AJAX calls

One of the challenges I'm facing is with buttons on a webpage that are part of the class "go". The code snippet below demonstrates how I handle actions related to these buttons: $(".go").live('click', this.handleAction); The issue arises w ...

What issue lies within this particular for loop?

Hey everyone, I'm having trouble with my code that involves appending an array to the DOM. Here's what I have: function inputFeedContent(data){ for(var k=0; k < columns; k++) { var col = "<div class='col-1'>"; ...

Saving a revised JSON file using AngularJS

Currently, I am in the process of developing a phonegap application using AngularJS that relies on a .json file to store an array of entries. The main goal I am aiming for is to enable users to mark specific entries as favorites and then utilize that data ...