1

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

1
  • Please read How to Ask, which notes "DO NOT post images of code, data, error messages, etc. -- copy or type the text into the question." Commented Oct 18, 2021 at 22:55

1 Answer 1

1

__ob__ is an internal property used by Vue's reactivity system, and should not be manually modified.

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.planImages = [];       👇
  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: "",
      }
    });
  });
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.