angular - Angular Rxjs forkJoin 错误:无法读取未定义的属性“订阅”
问题描述
我正在尝试将多个附件添加到 SharePoint 列表项。服务方法接受附件列表,它应该在所有文件上传后才返回响应(Sharepoint API 一次只接受一个文件)。所以我为此目的使用 rxjs forkJoin。
下面是我写的服务类。
import { Injectable } from '@angular/core';
import { Observable, forkJoin } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http'
import { ContextService } from './context.service'
import { mergeMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AttachmentService {
constructor(private httpClient: HttpClient) { }
addAttachmentsToTheList(listName: string, listItemId: number, attachmentList: any[], diagest: any) {
//get the file upload observable list
let fileUploadOnservables: any[] = [];
attachmentList.forEach(file => {
fileUploadOnservables.push(this.addAttachment(listName, listItemId, file, diagest))
});
// use forkJoin to combine the operations and subscribe to all results
// use forkJoin to combine the operations and subscribe to all results
forkJoin(fileUploadOnservables)
.subscribe(
(response) => {
//after all the successful requests do something
}
);
}
}
//this will add a single attachment to list
addAttachment(listName: string, listItemId: number, file: any, diagest: any) {
//first read the file as buffer, and pass the buffer to the Sharepoint REST API
return this.getFileBuffer(file)
.pipe(
mergeMap((fileBuffer: any) => {
//once file buffer observable returns pass the buffer to the Sharepoint REST API
return this.httpClient.post(
"../_api/lists/GetByTitle('" + listName + "')/items(" + listItemId + ")/AttachmentFiles/add(FileName='" + file.name + "')",
fileBuffer,
{
headers: new HttpHeaders({
'X-RequestDigest': diagest,
'Accept': 'application/json; odata=verbose',
'Content-Type': 'application/json; odata=verbose'
})
})
})
);
}
//this returns the file buffer
getFileBuffer(file) {
return new Observable(subscriber => {
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function (e: any) {
subscriber.next(e.target.result);
subscriber.complete();
};
});
}
}
在组件中:
someMethod(){
this.attachmentService.addAttachmentsToTheList('SomeList', 1, this.attachmentList,diagest)
.subscribe(
(result: any) => {
//do something
},
(error: any) => {
//handle error
});
}
此代码会引发以下错误,但它也会上传文件。我在这里做错了什么,如何解决这个错误?
Cannot read property 'subscribe' of undefined
感谢你的帮助。
解决方案
原始答案
看起来错误是由于您从组件订阅服务中方法的结果而引起的,但是服务中的方法实际上并未向组件返回任何内容。您应该能够通过从服务中的方法返回结果并将forkJoin
从服务中的方法移动subscribe()
到组件来解决此错误。我建议在您的方法中添加返回类型,因为这将有助于在将来更好地捕获与此类似的错误。
addAttachmentsToTheList(listName: string, listItemId: number, attachmentList: any[], diagest: any): Observable<...> {
//get the file upload observable list
let fileUploadOnservables: any[] = [];
attachmentList.forEach(file => {
fileUploadOnservables.push(this.addAttachment(listName, listItemId, file, diagest))
});
// use forkJoin to combine the operations and subscribe to all results
return forkJoin(fileUploadOnservables);
}
如果你在 fork 加入后需要在服务中执行进一步的操作fileUploadOnservables
,那么你可以使用该pipe
功能:
return forkJoin(fileUploadOnservables).pipe(...);
更新的答案
您可以尝试使用from
运算符将值列表拆分为单个事件,然后使用toArray
运算符组合每个事件。
addAttachmentsToTheList(listName: string, listItemId: number, attachmentList: any[], diagest: any): Observable<...> {
return from(attachmentList).pipe(mergeMap(value => this.addAttachment(listName, listItemId, value, diagest)), toArray());
}
推荐阅读
- amazon-redshift - 如何在一个组内的列中使用多个十进制数字?
- python - 比较日期的列表表示或比较日期时间对象的实用性
- typescript - 如何使用 Typescript 正确转换模拟函数
- macos - SwiftUI 菜单按钮最初显示为禁用
- java - 多对多关系中 MAX id GROUP BY FOREIGN KEY 的 JPA 标准
- javascript - VueJS 正在更新事件中的另一个元素
- javascript - 在“for...in”语句中应用过滤器
- php - 将php变量转换为Excel
- c++ - 了解关于 EMC++ 第 41 项的勘误表的评论
- symfony - 当用户关闭浏览器时向数据库发出请求