Search code examples
angulartypescriptblobfilecontentresult

Read file and its properties from API and download it in Angular Client


Need to download dynamic files which is returned from the api in the client side based on its type. This is what i have

My api controller it looks like this

    public async Task<IActionResult> GetFile(int id)
    {

         IBaseResult<UserDetails> result = await _Bo.GetUSerDetails(id);
         
         //result will have content likes 

         //1. FileName//fileaname.{extention}
         //2. FileType//eg.application/pdf or application/doc
         //3. FileContent//byte[]

         if (result.Data != null)
         {
             response.Success = result.success;
             response.Data = result.Data;

             return Ok(response);
         }
     }

.ts file looks like this

  data.service.ts

  getResume(methodName: string, id :string): Observable<any> {
       let httpOptions = this.getAuthoriseHeader();
       return this.http.get(environment.baseApiUrl + methodName + id, { headers: httpOptions, observe: 'response', responseType: 'blob' });

   }

  view.component.ts

     this.dataservice.getResume(method, id).subscribe(result => {
         var resume = result["data"];
         var fileName = resume.resumeName;
         var fileType = resume.resumeType;

         const file = new Blob([resume.resume], { type: fileType  });//Is this correct or do i need to use 'application/octet-stream' here?

         saveAs(file, fileName);
     });

With above implementation file is downloading but when i try to open the file, below is showng

enter image description here

And my response object is

enter image description here

UPDATE:

I tried this in my .ts file

var fileName = resume.resumeName; var fileType = resume.resumeType; //var byteArray = new Uint8Array(resume.resume);

      const file = new Blob([resume.resume], { type: 'application/octet-stream' });

      this.fileUrl = this.sanitizer.bypassSecurityTrustResourceUrl(window.URL.createObjectURL(file));

      let a = document.createElement('a');
      document.body.appendChild(a);
      a.setAttribute('style', 'display: none');
      a.href = this.fileUrl;
      a.download = fileName;
      a.click();
      window.URL.revokeObjectURL(this.fileUrl);
      a.remove();

File is downloading with Failed - No file error


Solution

  • Finally i found solution and its working fine now. As i suspected it was issue with converting my blob data to save.

     const binaryString = window.atob(resume.resume); // Comment this if not using base64
     const bytes = new Uint8Array(binaryString.length);
     return bytes.map((byte, i) => binaryString.charCodeAt(i));
    

    and then i used

    const blob = new Blob([body]);
    //rest of the code is same as posted question
    

    This article really helped with solution

    https://medium.com/@riccardopolacci/download-file-in-javascript-from-bytea-6a0c5bb3bbdb