I am currently developing a service that is responsible for uploading a list of files to a backend server.
createFiles(formData: any, userToken: string): Observable<any> {
const headers = new HttpHeaders({'Authorization': 'Bearer ' + userToken});
const filesUrl = this.constants.HOST_URL + 'files';
return this.http.post(
filesUrl, formData,
{
headers: headers,
reportProgress: true,
observe: 'events'
}
)
.pipe(
catchError(this.handleError)
);
}
This particular service can be utilized within a component in the following manner:
export interface Upload {
content: any | null;
progress: number;
state: 'PENDING' | 'IN_PROGRESS' | 'DONE';
}
upload: Upload;
constructor( private fileService: FileService,) {}
this.fileService.createFiles(this.formData, this.token)
.subscribe(
(event: HttpEvent<any>) => {
switch (event.type) {
case HttpEventType.Sent:
this.upload = {content: null, progress: 0, state: 'PENDING'};
break;
case HttpEventType.UploadProgress:
this.upload = {
content: null,
progress: Math.round((event.loaded / event.total) * 100),
state: 'IN_PROGRESS'
};
console.log(this.upload.progress);
break;
case HttpEventType.Response:
this.upload = {
content: event.body,
progress: 100,
state: 'DONE'
};
console.log(this.upload.state);
break;
default:
this.upload = {
content: null,
progress: 0,
state: 'PENDING'
};
}
if (this.upload.state === 'DONE') {
this.files = this.upload.content;
}
}, error => {
this.errorMessage = <any>error;
console.log(this.errorMessage);
}
);
}
In the component's template, there is a progress bar that visually represents the upload progress:
<mat-progress-bar [mode]="upload?.state == 'PENDING' ? 'buffer' : 'determinate'"
[value]="upload?.progress">
</mat-progress-bar>
A common issue encountered during large file uploads is that the progress bar quickly moves from 0 to 100, then tends to stay at 100 for an extended duration before transitioning to the DONE
status.
An observation from the logs indicates a significant delay between the last UploadProgress
event and the subsequent Response
event triggering the DONE
state in the Upload object.
https://i.sstatic.net/5lHXj.png Despite referencing Angular's official guides, I still find myself perplexed on how to synchronize the progress visualization with the actual upload status.