0

How does one trigger click event on a <a></a> html element in ngFor. I want file download for each shipment attachment. I hope the code below is enough demonstrating. Code:

attachments.component.ts

export class ShipmentDetailsAttachmentsComponent implements OnInit {

  @Input("shipment")
  public _shipment: Shipment;

  constructor(private _shipmentService: ShipmentService) {}

  ngOnInit() {}

  public getAttachment(shipmentId: number, attachmentId: number) {

    this._shipmentService.getShipmentAttachment(shipmentId, attachmentId).subscribe((content: Blob) =>
    {
      // file is transfered Ok, I get blob content
      let url = window.URL.createObjectURL(content);
      let link = this.clickedHtmlAelement; // here I want to get the clicked HTML element
      link.href = url;
      link.download = 'fileName';
      link.click();

      window.URL.revokeObjectURL(url);

    }, (error: MessageModel) => { 
      console.log("failed to retrieve attachment content");
  });
}

attachments.component.html

<div *ngFor="let attachment of _shipment.attachments">
  <a (click)="getAttachment(_shipment.id, attachment.id)">{{attachment.name}}</a>
</div>

If I create <a> element on the fly it works, but I believe there is a better solution:

  let url = window.URL.createObjectURL(content);      
  var a = document.createElement('a');
  document.body.appendChild(a);
  a.setAttribute('style', 'display: none');
  a.href = url;
  a.download = "file";
  a.click();
  window.URL.revokeObjectURL(url);
  a.remove(); // remove the element*/

In case anyone is interested -> working code for file-download:

typescript

let url: string = this.getFullUrl(`/api/v1/shipments/${shipmentId}/attachments/${attachmentId}`);
let headers: HttpHeaders = new HttpHeaders().set('Authorization', this.token);

return this._httpClient.get(url, {
  headers: headers,
  responseType: 'blob' // this is very important, ajax setting responseType
})
.pipe(
  catchError(this.handleError)
);
broadband
  • 3,266
  • 6
  • 43
  • 73

1 Answers1

0

You can use file-saver

  import * as FileSaver from 'file-saver';

  this._shipmentService.getShipmentAttachment(shipmentId, attachmentId)
    .subscribe(data => {
      FileSaver.saveAs(data.content, data.fileName);
    },
    error => {
      console.error('Download Error', error);
    },
    () => console.log('Completed'));

and in the service:

this.http.post(`/my/download`,
            data, 
            {responseType: 'blob', observe: 'response'})
          .map( res => ({content: res.body, 
                         fileName: res.headers.get('content-filename')}));
sabithpocker
  • 15,274
  • 1
  • 42
  • 75