简体   繁体   中英

__ob__: Observer instead of my array of objects ( JSON.parse(JSON.stringify(obj)) NOT WORKING )

I need to input files in alphabetical order, and when I pass the files from one array to another the order is mixing up. Here is the method that takes the files:

updatePreviews() {
  if (this.plan.gallery == null || this.plan.gallery.length == 0) {
    this.plan.gallery = [];
  }

  if (this.files?.length == 0) {
    this.planImages = this.oldImages.filter((o) =>
      this.planImages.map((o) => o.name).includes(o.name)
    );
  }
  this.files.forEach((file) => {
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    fileReader.addEventListener("load", () => {
      if (
        !this.planImages
          .map((g) => g.name)
          .includes(file.name)
      ) {
        this.planImages.push({
          name: file.name,
          type: this.viewTypes[0],
          url: fileReader.result,
          description: "",
        });
      }
    });
  });
}

Now see what happens when I log this.files The order is fine (Line 417)

But when I log this.planImages (Which I call from vue) This is what happenes They are wrapped into an observer and the order is different than the array of files. This is the vue code where I call this.planImages to be displayed and it works fine

<v-row v-for="(image, index) in this.planImages" :key="index">
      <v-text-field
        label="Name"
        class="ma-4"
        v-model="image.name"
        readonly
        full-width
      ></v-text-field>
      <v-combobox
        class="ma-4 mt-10"
        label="View Type"
        v-model="image.type"
        :items="viewTypes"
      ></v-combobox>
      <v-icon class="pt-4 pr-4" @click="deleteImage(index)"
        >mdi-delete</v-icon
      >
    </v-row>

Now... I think this is because the file's name has special characters like "()", but I can't apply any sort method because I can't access anything since the files are nested into the observer.

I've been dealing with this for a while now and here are some of the things I tried and the result:

The most common solution I saw is

 const testJSON = JSON.parse(JSON.stringify(this.planImages));
  console.log(testJSON);

This just gives me an empty array back

The only thing that seemed to work for me was:

this.planImages.__ob__ = new Object({});

Which gives me this back As you see it gives me back an array with the files (Still mixed up) but it prints this error: Uncaught TypeError: ob.observeArray is not a function

I couldn't figure out a way out of this, if someone could please tell me why I can't get to the root of all this I would really appreciate it

The __ob__ is an internal property used by Vue's reactivity system, and that should not be modified by your code.

The element order of this.planImages differs because its array elements are pushed upon the FileReader 's load event, which occurs at different times based on the file sizes. The order seen in this.planImages is likely smallest file to largest file.

To preserve the array order, insert the loaded files into the new array at the original index:

updatePreviews() {
  ⋮                            👇
  this.files.forEach((file, index) => {
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    fileReader.addEventListener("load", () => {
      ⋮                 👇
      this.planImages[index] = {
        name: file.name,
        type: this.viewTypes[0],
        url: fileReader.result,
        description: "",
      }
    });
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM