Nithin Paul
Nithin Paul

Reputation: 2199

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

Upvotes: 0

Views: 3380

Answers (2)

Nithin Paul
Nithin Paul

Reputation: 2199

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

Upvotes: 2

Emilien
Emilien

Reputation: 2761

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

Upvotes: 1

Related Questions