how to create a downloadable link which loads the file from a backend server only when clicked...

Discussão em 'Angular' iniciado por binga58, Novembro 17, 2024.

  1. binga58

    binga58 Guest

    I have a situation where I have a list of items each represent a file. All these files can be fetched from a backend as blobs. I want to have links in the frontend when user clicks should be able to download the file for him/her.
    The solution I have pre downloads the file and creates a SafeResourceUrl.

    But, my problem is since I now have to show a list of links pre downloading all of them initially is a waste. I need to make it such that when I click the link the network call will go and fetch the file and then the download popup should be opened.

    here is the code I have for predownloading

    component

    import { Component, OnInit } from '@angular/core';
    import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
    import { AppService } from './app.service';
    import { HttpResponse } from '@angular/common/http';

    @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    })
    export class AppComponent implements OnInit {
    url?: SafeResourceUrl;
    stream: ArrayBuffer | null = null;
    fileName: string = 'test.pdf';

    constructor(
    private appService: AppService,
    private sanitizer: DomSanitizer
    ) {}

    ngOnInit(): void {
    this.appService.fetchPdf().subscribe((response: HttpResponse<Blob>) => {
    const blob = response.body!;
    blob.arrayBuffer().then((res) => {
    this.stream = res;
    });
    this.createLink(blob);
    });
    }

    async createLink(blob: Blob): Promise<void> {
    const buffer = await blob.arrayBuffer();
    if (buffer.byteLength) {
    const uint = new Uint8Array(buffer);
    let bin = '';
    for (let i = 0; i < uint.byteLength; i++) {
    bin += String.fromCharCode(uint);
    }
    const base64 = window.btoa(bin);
    const url = `data:${blob.type};base64,${base64}`;
    this.url = this.sanitizer.bypassSecurityTrustResourceUrl(url);
    }
    }
    }



    service

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpResponse } from '@angular/common/http';
    import { Observable } from 'rxjs';

    @Injectable({
    providedIn: 'root',
    })
    export class AppService {
    private pdfUrl =
    'https://s28.q4cdn.com/392171258/files/doc_downloads/test.pdf';

    constructor(private http: HttpClient) {}

    fetchPdf(): Observable<HttpResponse<Blob>> {
    return this.http.get(this.pdfUrl, {
    observe: 'response',
    responseType: 'blob',
    });
    }
    }



    html

    <h1>download test</h1>
    <div *ngIf="url">
    <a [href]="url" [download]="fileName">{{ fileName }}</a>
    </div>



    here is demo

    Continue reading...

Compartilhe esta Página