Home > Blockchain >  Why does it change all values for me every time I add an element to the array?
Why does it change all values for me every time I add an element to the array?

Time:05-23

Every time I add an element it automatically replaces all the others but this happens to me only if I insert the whole object if I insert a classic element an integer a string works without problems.

 <body>
    <div id="app">
      <button @click="post()">POST</button>
      <h1>{{ar.name}} {{ar.surname}} {{ar.gender}}</h1>
      <br />
      <hr />
      <div v-for="(value, index) in array">
        <text>{{index}} {{value}} </text>
      </div>
    </div>

    <script src="https://unpkg.com/vue@3"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script>
      let app = Vue.createApp({
        data: function () {
          return {
            ar: {
              name: "",
              surname: "",
              gender: "",
            },
            array: [],
          };
        },
        methods: {
          async post() {
            await axios
              .get("https://randomuser.me/api/")
              .then((r) => {
                arr = r.data.results;
                arr.forEach((element) => {
                  this.ar.name = element.name.first;
                  this.ar.surname = element.name.last;
                  this.ar.gender = element.gender;
                  this.array.push(this.ar);
                });
              })
              .catch((err) => {
                console.log("Error "   err);
              });
          },
        },
      });
      app.mount("#app");
    </script>
  </body>
</html>

first element insert

second element insert

CodePudding user response:

You have a pointer reference issue. You actually add the same object pointer several times to the array, i.e. the same object reference:

Explaination of the problem

const obj = { name: 'ref1' };

const array = [];
array.push(obj);
array.push(obj);
array.push(obj);

// array === [{ name: 'ref1' }, { name: 'ref1' }, { name: 'ref1' }]
// which is actually [$objRef1, $objRef1, $objRef1] where $objRef1 is a pointer to the object address.

// when you updates the object,
obj.name = 'Hello'

// you still have array = [$objRef1, $objRef1, $objRef1] where $objRef1 all referes to this object: { name: 'Hello' }
// array === [{ name: 'Hello' }, { name: 'Hello' }, { name: 'Hello' }]

Solution:

You have to create a new object on every iteration, so they all are distinct object which a distinct address (pointer).

await axios
  .get("https://randomuser.me/api/")
  .then((r) => {
    const arr = r.data.results;
    arr.forEach((element) => {
       const item = {
          name: element.name.first,
          surname: element.name.last,
          gender: element.gender,
       };
       this.ar = item // refers to the new created item
       this.array.push(item);
     });
   }).catch((err) => {
      console.log("Error "   err);
   });

CodePudding user response:

You can assign the response in an object inside the iteration and pass that in the this.ar. Try this way :

const URL = "https://randomuser.me/api/";
new Vue({
  el: '#app',
  data() {
    return {
      ar: {
        name: "",
        surname: "",
        gender: "",
      },
      userArray: [],
    }
  },
  methods: {
    post() {
      axios.get(URL).then((r) => {
        arr = r.data.results;
        arr.forEach((element) => {
          let obj = {};
          obj.name = element.name.first;
          obj.surname = element.name.last;
          obj.gender = element.gender;
          this.ar = obj;
          this.userArray.push(obj);
        });
      })
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.17.1/axios.js"></script>
<div id="app">
  <button @click="post()">POST</button>
  <h1>{{ar.name}} {{ar.surname}} {{ar.gender}}</h1>
  <br />
  <hr />
  <div v-for="(value, index) in userArray" :key="index">
    <span> {{index}} {{value}} </span>
  </div>
</div>

  • Related