Bryton Beesley
Bryton Beesley

Reputation: 179

Object property is unsetting itself

After setting a uuid4 object property either by the Object.assign or Object.defineProperty methods, the property sometimes unsets itself in Safari without explanation, as in the following minimal reproducible example.

I have not observed this issue in Chrome.

To reproduce using this example on a local machine, I would click the "Choose Files" buttons and select files from my local file system. The script preview-uploads.js will then assign the uuid4 property, which uploads-manager.js will subsequently attempt to read and print to console with console.log(file.uuid4).

The example uses local files, so you'll need to disable local file restrictions in Safari as described here to run this example.

The issue occurs inconsistently in this minimum reproducible example. It took me about 20-30 trials before it occurred again, as confirmed by the screenshot below which shows how console.log(file.uuid4) printed "undefined" to the console. However, in the complicated use case where I am applying it (and which is too big and proprietary to post), it happens nine times out of ten.

There is no obvious pattern that I observe. I've paid attention to the file types and file sizes that I'm experimenting with, and the issue bears no obvious correlation to either.

Can someone please help me understand what is causing the property to unset in this apparently random way?

(By the way, the ajax method of building the html is important to my proprietary use case, which is why I've included it in the MRE.)

Screenshot

enter image description here

test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.6.0.js"></script>
</head>
<body>
</body>
<script>
    $(document).ready(function () {
        $.ajax({
            type: 'GET',
            url: 'file:///path/to/test_ajax.html',
            success: function (response) {
                $('body').html(response);
            }
        })
    });
</script>
</html>

test_ajax.html

<script src="/path/to/preview-uploads.js"></script>
<div>
    <div id="files-test1">
        <input autocomplete="off" multiple="true" name="files[]"
               onchange="previewFiles('test1');uploadFiles()" type="file">
    </div>
    <div class="grid-test1 padding-top-15" data-uuid4list="">
        <a href="" target="_blank"><img/>
        </a>
    </div>
</div>
<div>
    <div id="files-test2">
        <input autocomplete="off" multiple="true" name="files[]"
               onchange="previewFiles('test2');uploadFiles()" type="file">
    </div>
    <div class="grid-test2 padding-top-15" data-uuid4list="">
        <a href="" target="_blank">
            <img/>
        </a>
    </div>
</div>
<script src="/path/to/upload-manager.js"></script>

preview-uploads.js

function previewFiles(fileId) {
  var files   = document.querySelector('[id="files-' + fileId.replace('.','\\.') + '"]>input').files;

  if (files) {
    [].forEach.call(files, function(file) {
      let uuid4 = '09832a0d-86c4-4a9f-ab93-23bac596b83b';
      Object.assign(file, {'uuid4': uuid4});
    });
  };
};

upload-manager.js

function uploadFiles() {
    var formData = new FormData();
    $("input[type='file']").each(function() {
        $.each(this.files, function(i, file) {
            formData.append('files[]', file, file.uuid4 + ':' + file.name);
            console.log('file.uuid4 will follow next');
            console.log(file.uuid4);
        });
    });
};

Upvotes: 1

Views: 75

Answers (0)

Related Questions