Saturday, 23 July 2022

Upload status for every file in JS

I'm trying to build input to upload multiple files and get response from server to update a UI.

I built something like this using jQuery:

function UploadFile(file) {
  return new Promise((resolve) => {
    $.ajax({
      url: "/api/admin/upload",
      type: "POST",
      data: file,
      processData: false,
      contentType: false,
      success: function (data) {
        var d = JSON.parse(data);
        if (d.error_info) {
          resolve({ r: "error", i: d.error_info });
        } else if (d.success_info) {
          resolve({ r: "success", i: "Ok" });
        } else if (d.fileexists) {
          resolve({ r: "fileexists", i: "Ok" });
        } else {
          resolve({ r: "error-0", i: data });
        }
      },
      error: function (data) {
        console.log(data);
        resolve({ r: "error-0", i: "ajax error" });
      },
    });
  });
}
$(document).on("change", "input", async function (e) {
  e.preventDefault();
  var files = $("input").prop("files");
  $.each(files, function (k, file) {
    //draw ui
  });
  $.each(files, async function (key, file) {
    var formData = new FormData();
    formData.append(`${key}`, file);
    let FileNo = key + 1;
    let TotalFiles = files.length;
    var result = await UploadFile(formData);
    console.log(result);
    switch (result.r) {
      case "success":
        StatusIco.html(
          '<i class="fa-solid fa-circle-check" data-info="Done"></i>'
        );
        break;
      case "error":
        StatusIco.html(
          `<i class="fa-solid fa-circle-xmark" data-info="${result.i}"></i>`
        );
        break;
      case "fileexists":
        StatusIco.html(
          '<i class="fa-solid fa-circle-exclamation" data-info="File exists"></i>'
        );
        break;
      default:
        console.log(result.i);
        StatusIco.html(
          '<i class="fa-solid fa-circle-xmark" data-info="Unknown error"></i>'
        );
        break;
    }
    //update total
    let percentage = Math.round((100 * FileNo) / TotalFiles) + "%";
    $(".uploading .percentage").html(percentage);
    $(".uploading .head .text").html(`Uploaded ${FileNo} from ${TotalFiles}`);
    //if last file
    if (FileNo == TotalFiles) {
      $(".uploading .head .text").html("Done");
    }
  });
});

Everything should work just fine, but sometimes number of total files + percentage wound get updated. Sometimes even my status icon will get stuck on uploading.

I need to upload them one by one because I have server file size limit and slow connection so if I upload more I'll get 500 error or timed-out.

I tried to use promise.then but ended up with the same result.

Ty for help!



from Upload status for every file in JS

No comments:

Post a Comment