Search code examples
drag-and-dropangular8

Angular8 - Getting File a Binary String from a Drop Zone File


In my Angular8 app, I have a drop zone where I can drag & drop files, such as PDF, MS Word, CSV, etc. I am using the technique found on this blog, but also documented by Mozilla MDN. The code works very well, but the one important thing I can't figure out is how to capture the file bytes being uploaded, so that I can save them to the database.

I placed a screenshot of the Opera browser source debugger below, showing the typescript and resulting fileObj and blobObj values. The debugger complains about readAsBinaryString(blobObj), saying that blobObj is not a Blob. Looking at the blobObj value, I can see it's not a Blob that I've seen before. And, looking at all the values, none stand-out to me as a Blob. Also, the file bytes aren't obvious either. Looking at the html, below, I can't think of a change that would reveal the bytes.

I'm hoping someone with drag and drop experience can explain how it's done.

Thanks!

Debugger Screenshot enter image description here

HTML

<table class="table table-striped table-forum">
  <tbody>
    <tr>
      <td>
        <div class="container" style="float: left; padding-top: 10px; padding-left: 10px;" appDnd (fileDropped)="onFileDropped($event)" (itemDropped)="onItemDropped($event)">
          <input type="file" #fileDropRef id="fileDropRef" multiple (change)="fileBrowseHandler($event.target.files)" />
          <img src="assets/img/dnd/ic-upload-file.svg" alt="">
          <h3>Drag and drop file here</h3>
          <h3>or</h3>              
          <label for="fileDropRef" style="font-size: 14px; font-weight: 600; height: 25px; padding: 5px 5px;">Browse for File</label>
        </div>
      </td>
    </tr>
    <tr>
      <td>
        <div class="files-list" style="width: 35%;">
          <div class="single-file" *ngFor="let file of files; let i = index">
            <img src="assets/img/dnd/ic-file.svg" width="45px" alt="file">
            <div class="info">
              <h4 class="name">
                {{ file?.name }}
              </h4>
              <p class="size">
                {{ formatBytes(file) }}
              </p>
              <app-progress [progress]="file?.progress" style="width: 200px;"></app-progress>
            </div>
            <img src="assets/img/dnd/ic-delete-file.svg" class="delete" width="20px" alt="file" (click)="deleteFile(i)">
          </div>
        </div>
      </td>
    </tr>
  </tbody>
</table>

Solution

  • const reader = new FileReader();
    
    // FileReader has an onload event that you handle when it has loaded data
    reader.onload = (e: any) => {
      const data = e.target.result as any;
      console.log({type: 'GalleryComponent prepareFilesList - data:', data});
    };
    
    // this will kick off the onload handler above
    reader.readAsDataURL(file);