Search code examples
javascriptarraysevents

Javascript: Global array loose content between events


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);
      }
    }
  });
});

Solution

  • 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....