javascripthtmlarraysfile-uploadlocalforage

Array.includes not working as expected with html file upload and localforage


So basically I'm making a website which allows the user to upload a .txt file and returns it for downloading it after encrypting it using a shift cipher.

I have the following HTML code

<div class="file-inp mainscreen-row-element level-2 enc">
   Upload Text File
</div>
<input type="file" accept=".txt" id="inp-elem" hidden />

And I am storing some data in indexedDB if it isn't already there

localforage.getItem("encrypton-caesar-cipher").then(d => {
  if (d == null) {
    localforage.setItem("encrypton-caesar-cipher", {
      enc: { inp: { text: [], files: [] }, out: { text: [], files: [] } },
      dec: { inp: { text: [], files: [] }, out: { text: [], files: [] } },
      ai: { inp: { text: [], files: [] }, out: { text: [], files: [] } }
    });
  }
});

And i my javascript includes this code

$(".file-inp").on("click", e => {
  $("#inp-elem").trigger("click");
  $("#inp-elem").on("change", () => {
    const f = $("#inp-elem").prop("files");
      localforage.getItem("encrypton-caesar-cipher").then(d => {
        if (!(d.enc.inp.files.includes(f))) {
          d.enc.inp.files.push(f);
          localforage.setItem("encrypton-caesar-cipher", d);
        }
      });
  });
});

So as the user uploads a file, i store the object in indexedDB with the help of localForage, and I have this conditional

if (!(d.enc.inp.files.includes(f)))

because i want to make sure I'm not storing the same object repeatedly

Now if I upload a file a.txt and go to the Dev Tools it is shown there, and if upload it again, my indexedDB data does not change, which is what I expect, but when I refresh the page, and then upload a.txt again, the same object is stored and shown in the Dev Tools twice, and this continues to increase if I reload the page and upload the same file.

I want to know what I'm doing wrong or is there a possible workaround?


Solution

  • The problem is that two javascript objects with the same content are not considered equal:

    const object1 = {foo: 'bar'};
    const object2 = {foo: 'bar'};
    object1 == object2 // false
    // but
    object1 == object1 // true
    

    But this works for primitives like string:

    const string1 = 'foo';
    const string2 = 'foo';
    string1 == string2 // true
    

    Maybe what you want is to use $("#inp-elem").val() which represents the path to the selected file and not the file itself. You can also calculate file contents hash if path is not what you want.