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

2

0

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

Terenceterencio answered 6/1, 2021 at 9:48 Comment(0)
T
2

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

Terenceterencio answered 6/1, 2021 at 11:13 Comment(0)
C
1

Here is how I did to download a file (Excel in my case, but I don't think it's different since we're both using Blob). I've installed ngx-filesaver and use it as dependency injection.

import { FileSaverService } from 'ngx-filesaver';

constructor(
  private http: HttpClient,
  private fileSaver: FileSaverService
) {}

export(): Observable<any> {
  const body = {...};
  return this.http.post(`${environment.api}/export`, body, {
      responseType: 'blob',
      observe: 'response',
    });
}

anotherFunction() {
  this.export().subscribe(({ body, headers }: HttpResponse<any>) => {
    const blob = new Blob([body], { type: headers.get('content-type') });
    this.fileSaverService.save(blob, 'your_file_name.xlsx');
  });
}

EDIT

Here is a screen of console.log(body, headers)

enter image description here

Canto answered 6/1, 2021 at 10:32 Comment(4)
Hi Emilien in your api controller how you are returning the doc details? can you share its snapshot? Also are you using content-disposition in your controller?Terenceterencio
Don't forget to use responseType: 'blob', observe: 'response', when you make your request. I've added a screenshot of what I get. I'm not using content-disposition.Canto
That i have in my implementation, but to draft this question i added selected items, i will update questionTerenceterencio
I managed it to find the solution Emilien, now its working, Please see my posted answer. thanks for your help....Terenceterencio

© 2022 - 2024 — McMap. All rights reserved.