Why my vuex store state chnage when i try to chnage the data using the method in my component?

Tazim Rahbar

I am making a small appliaction that allow the user to tell about their web application.

But In the Update component what I am doing is:

  • When a component is created.
  • Fetching the app from vue x store
  • Setting the values in the data property
  • And from data property taking it to the template

But the problem is when I try to update the stack of an app via methods addTechToStack by pushing the new value at the end of the app_stacks list it also changes the data of vuex state

Here is the code

<template>
  <div>
    <div class="section">
      <div class="box">
        <h1 class="title is-4 has-text-centered">Update App</h1>
        <hr class="has-background-black" />
        <form method="POST" @submit.prevent="">
          <div class="field">
            <label class="label">App Name:</label>
            <div class="control">
              <input
                class="input"
                type="text"
                placeholder="Enter App Name"
                v-model="updated.app_name"
              />
            </div>
          </div>
          <div class="field">
            <label class="label">App Subtitle:</label>
            <div class="control">
              <input
                class="input"
                type="text"
                placeholder="Enter App Subtitle"
                v-model="updated.app_subtitle"
              />
            </div>
          </div>
          <div class="field">
            <label class="label">App Url:</label>
            <div class="control">
              <input
                class="input"
                type="text"
                placeholder="Enter App Url"
                v-model="updated.app_url"
              />
            </div>
          </div>
          <div class="field">
            <label class="label">App Category:</label>
            <div class="control">
              <div class="select">
                <select v-model="updated.app_category">
                  <option value="" disabled>Select Category</option>
                  <option
                    v-for="(category, index) in categoreis"
                    :key="index"
                    :value="category"
                    >{{ category }}</option
                  >
                </select>
              </div>
            </div>
          </div>
          <div class="field">
            <label class="label">App Description:</label>
            <textarea
              class="textarea"
              placeholder="Description of your app"
              v-model="updated.app_description"
            ></textarea>
          </div>
          <!-- IMP:Stack section  -->
          <div class="field">
            <label class="label">App Stacks:</label>
            <div class="field has-addons">
              <div class="control">
                <input
                  class="input"
                  type="text"
                  placeholder="Find Technology"
                  v-model="updated.stackTech"
                  id="stackTech"
                />
              </div>
              <div class="control">
                <button class="button is-info" @click="addTechToStack">
                  Add
                </button>
              </div>
            </div>
          </div>
          <div class="box">
            <label class="label">Stacks:</label>

            <span
              class="tag is-medium mr-3"
              v-for="(tech, index) in updated.app_stacks"
              :key="index"
              >{{ tech }}
              <button
                class="delete is-small"
                @click="removeStack(index)"
              ></button>
            </span>
          </div>
          <!-- Stack section ends -->
          <div class="field is-grouped">
            <p class="control">
              <a class="button">
                Cancel
              </a>
            </p>
            <p class="control">
              <button
                type="submit"
                class="button is-primary"
                v-on:click="submitUpdate"
              >
                Update
              </button>
            </p>
          </div>
        </form>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Update",
  data() {
    return {
      currentApp: null,
      categoreis: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"],
      //   Contains the updated value
      updated: {
        app_name: "",
        app_subtitle: "",
        app_description: "",
        app_url: "",
        app_category: "",
        app_stacks: "",
        stackTech: "",
      },
    };
  },

  methods: {
    removeStack(index) {
      console.log("Removed");
      this.updated.app_stacks.splice(index, 1);
      console.log(this.currentApp);
      console.log(this.updated.app_stacks);
    },
    addTechToStack() {
      this.updated.app_stacks.push(this.updated.stackTech);
      console.log(this.currentApp.stacks);
      console.log(this.updated.app_stacks);
    },
    submitUpdate() {
      // Check if user has updated any content
      if (
        this.currentApp.app_name == this.updated.app_name &&
        this.currentApp.subtitle == this.updated.app_subtitle &&
        this.currentApp.app_url == this.updated.app_url &&
        this.currentApp.category == this.updated.app_category &&
        this.currentApp.description == this.updated.app_description &&
        this.currentApp.stacks.toLocaleString()==this.updated.app_stacks.toLocaleString()
      ) {
        console.log("Cannot Update Beasue every vlaue is the same");
        console.log(this.currentApp.description);
        console.log(this.updated.app_description);
        console.log(this.currentApp.stacks);
        console.log(this.updated.app_stacks);
      } else {
        console.log("Updated");
        console.log(this.currentApp.description);
        console.log(this.updated.app_description);
      }
    },
  },
  created() {
    // const current = this.$store.state.your_apps[this.$route.params.index];
    this.currentApp = this.$store.state.your_apps[this.$route.params.index];
    this.updated.app_name = this.currentApp.app_name;
    this.updated.app_subtitle = this.currentApp.subtitle;
    this.updated.app_url = this.currentApp.app_url;
    this.updated.app_category = this.currentApp.category;
    this.updated.app_description = this.currentApp.description;
    this.updated.app_stacks = this.currentApp.stacks;
    console.log(this.currentApp);
  }
};
</script>
Kapcash

The problem is you're assigning a reference the same object (array) to a different variable.

So this.updated.app_stacks === this.currentApp.stacks are both references to the same array. So if you mutate one, you mutate the other.

To avoid this, you'll have to create a copy of this array in order to create a new reference and detach both array.

If you array is hosting primitive values (i.e. not arrays or objects), you can make a shallow copy. There are a lot of ways to do so, here is one:

  this.updated.app_stacks = [...this.currentApp.stacks];

Side note: in your data() initialisation, this.updated.app_stacks should be an empty array, not an empty string. It doesn't change anything since you overwrite it in created, but it's kind of confusing when reading the code.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related