我目前正在尝试跟踪角度组件中的上传进度。该组件接受文件并调用服务,该服务会将文件上传到服务器。
我们目前使用拦截器来注入带有auth令牌的标头。
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (localStorage.getItem('token') != null) {
request = request.clone({
setHeaders: {
'X-Auth-Token': localStorage.getItem('token')
}
});
}
return next.handle(request).pipe(
map((event: HttpEvent<any>) => {
return event;
}),
catchError((error: any) => {
if (error.status === 401) {
localStorage.removeItem('token');
this.router.navigate(['/public/login']);
return of(error);
}
return throwError(error);
})
);
如果在此处的map()后面放置一个tap(),我可以接收到Tap笔记并将其记录到控制台。
我致电服务并尝试使用管道/点击在组件中获取上传进度
this.assetService.upload(formData).pipe(
map(data => console.log(data)),
tap(message => console.log(message))
).subscribe(data => { console.log(data); });
这里的pipe()/ map()/ tap()永远不会被命中。
理想情况下,我想使用组件中的tap()来计算上载的百分比,然后使用它来更新进度条。
答案 0 :(得分:3)
您可以使用此方法或方法使用RxJ的tap/map/pipe
。
postImportExportFile(fileToUpload: File): Observable<MyObject> {
this.formData = new FormData();
this.formData.append('file', fileToUpload, fileToUpload.name);
const url = 'http://loclahost:4200/myPost/url/to/be/hit';
return this.http.post(url, this.formData, {
headers: new HttpHeaders({ 'upload': 'true' }), // I used this for change the interceptors accepts and content-type
reportProgress: true,
observe: 'events',
}).pipe(
retry(3),
map((event: HttpEvent<any>) => this.getEventMessage(event, fileToUpload)),
tap((t: MyObject) => {
return console.log(`post import export file for );
}),
catchError(this.handleError<MyObject>(url))
);
}
方法:
getEventMessage(event: HttpEvent<any>, file: File): MyObject{
const myObject= new MyObject();
switch (event.type) {
case HttpEventType.Sent:
myObject.eventType = UploadEventType.SENT; // This is an enum that help me to add a event type to my object
myObject.message = `Uploading file "${file.name}" of size ${file.size}.`;
break;
case HttpEventType.UploadProgress:
myObject.eventType = UploadEventType.PROGRESS;
const percentDone = Math.round(100 * event.loaded / event.total);
myObject.message = `File "${file.name}" is ${percentDone}% uploaded.`;
break;
case HttpEventType.Response:
console.log(`File "${file.name}" was completely uploaded!`);
myObject.eventType = UploadEventType.COMPLETED;
myObject.message = event;
break;
default:
myObject.eventType = UploadEventType.ERROR;
myObject.message = `File "${file.name}" surprising upload event: ${event.type}.`;
}
return myObject;
}
收到对象后,您可以检查是否发生了什么情况,并根据需要进行工作。
在第一部分中,我使用了方法postImportExportFile
,该方法是后方法调用,并发送一个标头,该标头用于更改拦截器值,如headerSettings['Content-Type'] = 'multipart/form-data';
,然后使用观察类型:events
。
这可以帮助我们获得HttpEvent
,然后我们将身边的消息更改为检查和使用。第二种方法可以直接使用,但我将其破坏并用作自己的对象。
希望对您有所帮助。如果您需要进一步澄清代码,请告诉我。