0

Hi, I am using File reader api to read Multiple files and break the files into chunks and then upload, But the code is Working fine for single file, but in case of multiple files the last file only is uploading. Below is my code

     if (this.fileList.length > 0) {
      for (let i = 0; i < this.fileList.length; i++) {  this.handleFileSelect(this.fileList[i]);
    }
    }

    handleFileSelect(file: any) {
        console.log('handlefile');
        this.maxBlockSize = 1 * 1024 * 1024;
        this.currentFilePointer = 0;
        this.totalBytesRemaining = 0;
        this.selectedFile = file;

        let fileSize: number = this.selectedFile.size;
        console.log('filesize: '+fileSize);
        console.log('Block size: '+ this.maxBlockSize);

        if (fileSize < this.maxBlockSize) {
          this.maxBlockSize = fileSize;
          console.log("max block size = " + this.maxBlockSize);
        }
        this.totalBytesRemaining = fileSize;
         console.log("totalBytesRemaining = " + this.totalBytesRemaining);
        if (fileSize % this.maxBlockSize == 0) {
          this.numberOfBlocks = fileSize / this.maxBlockSize;
        } else {
          this.numberOfBlocks = Math.floor(fileSize / this.maxBlockSize) + 1;
         // this.numberOfBlocks = (fileSize / this.maxBlockSize, 10) + 1;
        }
        console.log("total blocks = " + this.numberOfBlocks );
        var baseUrl = 'xxxxxx';
        var indexOfQueryStart = baseUrl.indexOf("?");
        this.submitUri = baseUrl.substring(0, indexOfQueryStart) + '/' + this.selectedFile.name + baseUrl.substring(indexOfQueryStart);
        console.log(this.submitUri);




        this.uploadFileInBlocks();
      }

        uploadFileInBlocks() {
        console.log('uploadfileblock');
        if (this.totalBytesRemaining > 0) {

          console.log("current file pointer = " + this.currentFilePointer + " bytes read = " + this.maxBlockSize );
          var fileContent = this.selectedFile.slice(this.currentFilePointer, this.currentFilePointer + this.maxBlockSize);
          var blockId = this.blockIdPrefix + this.pad(this.blockIds.length, 6);
          console.log("block id = " + blockId);
          this.blockIds.push(btoa(blockId));
          this.reader.readAsArrayBuffer(fileContent);
          this.currentFilePointer += this.maxBlockSize;
          this.totalBytesRemaining -= this.maxBlockSize;
          if ( this.totalBytesRemaining < this.maxBlockSize ) {
            this.maxBlockSize = this.totalBytesRemaining;
          }
        } else {
          this.commitBlockList();
        }
      }

constructor(public http: Http) {
    this.fileString;
    this.progress$ = new Observable(observer => {
      this.progressObserver = observer
    }).share();

    this.reader.onloadend = (e) => {

      if (this.reader.readyState == this.reader.DONE) { // DONE == 2
       console.log(this.reader.result);
        var uri = this.submitUri + '&comp=block&blockid=' + this.blockIds[this.blockIds.length - 1];
        var requestData = new Uint8Array(this.reader.result);
        let that = this;
        var formData = new FormData();
                let xhr = new XMLHttpRequest();
                xhr.open("PUT", uri, true)
                xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
                xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                if (xhr.status === 200 || xhr.status === 201) {

                that.bytesUploaded += requestData.length;
                //that.progress[that.selectedFile.name] = ( that.bytesUploaded / parseFloat(that.selectedFile.size) * 100).toFixed(2);
                that.progress[that.selectedFile.name] = ((that.bytesUploaded / that.selectedFile.size) * 100).toFixed(2);
                console.log(that.bytesUploaded + '/' + that.selectedFile.size + '*' + 100);

                that.uploadFileInBlocks();
                } else {
                console.log(xhr.response);
                }
                }
                }
                xhr.upload.onprogress = (event) => {
                //this.progress[files.name] = Math.round(event.loaded / event.total * 100);

              //  console.log(that.progress);
                };
                xhr.send(requestData);






      }
    };
  }

Can anyone suggest how to modify the code intended by the loop at the bottom to execute setup Reader sequentially please.

Chinna M
  • 415
  • 2
  • 4
  • 17

1 Answers1

0

If you trace the value of that.selectedFile.name in reader.onloadend handler, you'll find that the file name remains the name of the last file. So, basically each upload overwrites the previous one. To avoid this, you should use closure at onloadend handler as below. See FileReader onload with result and parameter for more details.

this.reader.onloadend = (file) => {

    return (e) => {
        console.log(file.name);
        // ...
    }

})(blob);  // The Blob or File from which to read.
Aaron Chen
  • 9,835
  • 1
  • 16
  • 28