0

I am trying to have an array be available for all my events. I have defined it at the top of my code right after $(document).ready

When I use it in my first event I fill it up with values and that works well. When I try to use it in another events, the array exist but it is now empty. Note, the second event cannot be executed before the first one.

In the code below, my first event is $('#fileInput').on('change' and my second event is $("#btnSubmit").on('click'.

The array is named fileListProperty and I have tried the following to make it global:

  • var fileListProperty =[];
  • window.fileListPropery = [];

In both case it gets created, filled up by the first event but gets emptied when second event gets called on.

Here's the code:

$(document).ready(() => {
  var fileListProperty = [];

  $("#loaderContainer").hide();

  /********************************************************************
   * Click on browse button trigger the click on hidden type=file input
   *******************************************************************/
  $("#browseBtn").on('click', () => {
    $('#btnSubmit').addClass("btnSubmitDisabled");
    $("#formList").empty();
    $('#fileInput').click();
  });

  /********************************************************************
   * When a file as been selected
   *******************************************************************/
  $('#fileInput').on('change', () => {

    $("#loaderContainer").show();

    var files = $("#fileInput").prop("files"); //get the files
    var fileListValid = false;
    var fileListProperty = [];
    var nbFiles = 0;

    const dt = new DataTransfer();

    //Validate each files
    Array.from(files).forEach((file, index) => {

      if (file.name.indexOf(".pp7") >= 0) {

        let onLoadPromise = new Promise((resolve, reject) => {

          let reader = new FileReader();
          reader.onloadend = (evt) => { //When file is loaded. Async

            let fileContent = evt.target.result; //event.target.result is the file content

            if (fileContent.substr(0, 2) === "PK") { //File content that start with PK is most likely a ZIP file
              resolve(file.name, index);
            } else {
              reject(file.name, index);
            }
          }
          reader.readAsText(file);
        });

        onLoadPromise.then(
          (fileName, zeIndex) => {
            dt.items.add(file);
            fileListProperty.push({
              fileIndex: zeIndex,
              fileName: file.name,
              valid: true,
              message: "Valid PP7 file.",
              pctConversion: 0
            });
          },
          (fileName, zeIndex) => {
            fileListProperty.push({
              fileIndex: zeIndex,
              fileName: file.name,
              valid: false,
              message: fileName + " isn't a valid PP7 file. Cannot be converted.",
              pctConversion: 0
            });
          }
        ).finally(() => {
          nbFiles++;

          if (nbFiles === files.length) {
            DisplayFileList();
          }
        });

      } else {
        fileListProperty.push({
          fileIndex: index,
          fileName: file.name,
          valid: false,
          message: file.name + " isn't a PP7 file. Cannot be converted.",
          pctConversion: 0
        });
        nbFile++;

        if (nbFiles === files.length) {
          DisplayFileList();
        }
      }
    });

    var DisplayFileList = () => {

      //Check if at least 1 files is valid
      fileListProperty.forEach((propJSON) => {
        if (propJSON.valid) fileListValid = true;
      });


      $("#fileInput").prop("files", dt.files); // Assign the updates list



      $("#loaderContainer").delay(1500).hide(0, () => {
        BuildFormList();

        if (fileListValid) {
          $('#btnSubmit').removeClass("btnSubmitDisabled");
        } else {
          $('#pp7Form').submit((evt) => {
            evt.preventDefault();
          });
        }
      });


      //$("#fileInput").prop("files", null);
    }

    var BuildFormList = () => {

      fileListProperty.forEach((listProperty) => {

        $("#formList").append(
          `<div class="fileContainer" idx="${listProperty.fileIndex}">` +
          `    <div class="fileName">${listProperty.fileName}</div>` +
          `    <div class="fileMessage ${listProperty.valid ? 'valid' : 'error'}">${listProperty.message}</div>` +
          `</div >`);
      });
    }
  });

  /*******************************************************************
   * When the submit button is clicked
   ******************************************************************/
  $("#btnSubmit").on('click', () => {

    if ($("#fileInput").prop("files").length === 0) {
      $('#pp7Form').submit(evt => {
        evt.preventDefault();
      });
    } else {
      $('#pp7Form').submit(evt => {
        $("#pp7Form").ajaxSubmit();
        return false;
      });

      var nbFilecompleted = 0;
      var nbValidFile = fileListProperty.filter(element => {
        return element.valid;
      });
      var percentage = -1;

      while (nbFilecompleted < nbValidFile) {

        fileListProperty.forEach((file, idx) => {
          if (file.valid && file.pctConversion < 100) {

            percentage = -1;
            $.post('https://ol-portal-dev-nr.ca.objectiflune.com/getStat', {
              UUID: $("#uuid").val(),
              fileID: file.fileIndex
            }, (data, status, xhr) => {
              if (status === 'success') {
                percentage = JSON.parse(data).percentage;
                file.pctConversion = percentage;
                if (percentage === 100) {
                  nbFilecompleted++
                }
              } else {
                alert('An error has occurred, please contact [email protected]');
              }
            });
          }
        });

        setTimeout(() => {}, 500);
      }
    }
  });
});
6
  • var fileListProperty = [] declares a local variable, so you're not updating the global variable. Get rid of that. Commented Mar 30, 2023 at 20:44
  • There's alsio no need to put this in window. Put the variable declaration in the $(document).ready() function. Then it will be in scope of both event handlers. Commented Mar 30, 2023 at 20:46
  • @Barmar, if you look at my code, it is there that I have declared it. Commented Mar 30, 2023 at 20:48
  • No it isn't. You have window.fileListProperty = [];. That's not a variable declaration. Commented Mar 30, 2023 at 20:50
  • @Barmar, I have did what you said and note that this is what I did in the past and I still get the issue. Both attempt either with var or window gives me the same result. Commented Mar 30, 2023 at 20:53

1 Answer 1

1

Move the declaration of fileListProperty out of the $("fileInput").change handler to the $(document).ready handler.

$(document).ready(() => {
  let fileListProperty = [];

  $("#loaderContainer").hide();

  /********************************************************************
   * Click on browse button trigger the click on hidden type=file input
   *******************************************************************/
  $("#browseBtn").on('click', () => {
    $('#btnSubmit').addClass("btnSubmitDisabled");
    $("#formList").empty();
    $('#fileInput').click();
  });

  /********************************************************************
   * When a file as been selected
   *******************************************************************/
  $('#fileInput').on('change', () => {

    $("#loaderContainer").show();

    var files = $("#fileInput").prop("files"); //get the files
    var fileListValid = false;
    var nbFiles = 0;
    // rest of your code....
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.