How can I download (.exe
file which is in root path) and Upload a file from Angular 4?
I am new to Angular4 and typescript and .NET Core Web API.
I h
Download any file from the server using Angular 8+ and ASP.NET CORE 2+ version.
Controller implementation to download the file:
[HttpGet] [Route("download")] public async Task Download([FromQuery] string file) { var uploads = Path.Combine(_hostingEnvironment.WebRootPath, "uploads"); var filePath = Path.Combine(uploads, file); if (!System.IO.File.Exists(filePath)) return NotFound(); var memory = new MemoryStream(); using (var stream = new FileStream(filePath, FileMode.Open)) { await stream.CopyToAsync(memory); } memory.Position = 0; return File(memory, GetContentType(filePath), file); }
Create angular service
import { Injectable } from '@angular/core'; import { HttpClient, HttpRequest, HttpEvent, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable() export class DownloadService { private baseApiUrl: string; private apiDownloadUrl: string; private apiUploadUrl: string; private apiFileUrl: string; constructor(private httpClient: HttpClient) { this.baseApiUrl = 'http://localhost:5001/api/'; this.apiDownloadUrl = this.baseApiUrl + 'download'; this.apiUploadUrl = this.baseApiUrl + 'upload'; this.apiFileUrl = this.baseApiUrl + 'files'; } public downloadFile(file: string): Observable> { return this.httpClient.request(new HttpRequest( 'GET', `${this.apiDownloadUrl}?file=${file}`, null, { reportProgress: true, responseType: 'blob' })); } }
Create a model in angular
export interface ProgressStatus { status: ProgressStatusEnum; percentage?: number; } export enum ProgressStatusEnum { START, COMPLETE, IN_PROGRESS, ERROR }
Create a component to download a file
Create a child component to download a file. Following code in typescript file:
import { Component, Input, Output, EventEmitter } from '@angular/core'; import { HttpEventType } from '@angular/common/http'; import { UploadDownloadService } from 'src/app/services/upload-download.service'; import { ProgressStatus, ProgressStatusEnum } from 'src/app/models/progress-status.model'; @Component({ selector: 'app-download', templateUrl: 'download.component.html' }) export class DownloadComponent { @Input() public disabled: boolean; @Input() public fileName: string; @Output() public downloadStatus: EventEmitter; constructor(private service: UploadDownloadService) { this.downloadStatus = new EventEmitter(); } public download() { this.downloadStatus.emit( {status: ProgressStatusEnum.START}); this.service.downloadFile(this.fileName).subscribe( data => { switch (data.type) { case HttpEventType.DownloadProgress: this.downloadStatus.emit( {status: ProgressStatusEnum.IN_PROGRESS, percentage: Math.round((data.loaded / data.total) * 100)}); break; case HttpEventType.Response: this.downloadStatus.emit( {status: ProgressStatusEnum.COMPLETE}); const downloadedFile = new Blob([data.body], { type: data.body.type }); const a = document.createElement('a'); a.setAttribute('style', 'display:none;'); document.body.appendChild(a); a.download = this.fileName; a.href = URL.createObjectURL(downloadedFile); a.target = '_blank'; a.click(); document.body.removeChild(a); break; } }, error => { this.downloadStatus.emit( {status: ProgressStatusEnum.ERROR}); } ); } }
Add the following implementation in parent component:
progress {{percentage}}%
Add the following implementation in parent typescript component:
import { Component, OnInit } from '@angular/core'; import { UploadDownloadService } from 'src/app/services/upload-download.service'; import { ProgressStatusEnum, ProgressStatus } from 'src/app/models/progress-status.model'; @Component({ selector: 'app-filemanager', templateUrl: './file-manager.component.html' }) export class FileManagerComponent implements OnInit { public files: string[]; public fileInDownload: string; public percentage: number; public showProgress: boolean; public showDownloadError: boolean; public showUploadError: boolean; constructor(private service: UploadDownloadService) { } ngOnInit() { this.getFiles(); } private getFiles() { this.service.getFiles().subscribe( data => { this.files = data; } ); } public downloadStatus(event: ProgressStatus) { switch (event.status) { case ProgressStatusEnum.START: this.showDownloadError = false; break; case ProgressStatusEnum.IN_PROGRESS: this.showProgress = true; this.percentage = event.percentage; break; case ProgressStatusEnum.COMPLETE: this.showProgress = false; break; case ProgressStatusEnum.ERROR: this.showProgress = false; this.showDownloadError = true; break; } } }
DONE!