【发布时间】:2020-11-28 00:18:23
【问题描述】:
首先:我是 Angular 的新手,所以这里的术语可能是错误的。我希望我能得到理解。
我正在使用 API。端点 A 暴露 Tickets;这些Tickets 包含Attachments 的数组(0-*)。那些Attachments 不完整;在数据模型中,它们包含基础文件内容的 base64 字符串,但为了减少一般负载,Attachments 仅在从端点 B 获取时才完成。但是为了从端点 B 获取 Attachment,我需要 @ 987654330@'s id,我只能从端点 A 获得。
我需要做的是我从端点 A 获取 attachment.id,使用该 id 从端点 B 获取适当的 Attachment,并将端点 A 的结果中的 Attachments 替换为端点的结果B. 但是,由于Attachments 被检索为Observable,因此我不能简单地分配值。
以下 sn-p 是解决此问题的几种尝试之一,并且能够从 API 获取 Attachments,但它们没有按照我想要的方式分配。
ngOnInit(): void {
console.log(`getting ticket for id ${this.id}`);
this.ticket$ = this.ticketService.getTicket(this.id).pipe(
map((response:Ticket) => {
response.attachments.map((attachmentPartly:Attachment) => {
console.log(`getting attachment for id ${attachmentPartly.id}`);
let attachmentFilled = this.ticketService.getAttachment(attachmentPartly.id);
attachmentFilled.subscribe(att => console.log(`base64 content is: ${att.base64Content}`)); //for posterity: this line has been omitted in tests with no change in result
return attachmentFilled;
});
return response;
})
);
}
getTicket 返回一个Observable<Ticket>。 getAttachment 返回一个 Observable<Attachment>。
可以看出,我已经开始通过日志进行调试(因为 Angular 应用程序托管在一个更大的系统中,该系统还提供对端点的授权,我无法真正以正确的方式调试它......)和 base64值被写入控制台,因此至少部分代码可以按我的意愿工作。例如,对于文本/纯文本类型文件,我可以将值“SGV5IHRoZXJlLCByYW5kb20gcGVyc29uIGZyb20gU3RhY2tPdmVyZmxvdw”写入控制台,该值与我通过 Postman 手动执行查询时找到的值匹配。
我怀疑我正在尝试将 Observable (attachmentFilled) 分配给 Attachment[],但 TS 并未警告非法类型转换。查看 Chrome DevTools 中的网络选项卡,我看不到对getAttachments 的调用,只有对getTickets 的调用。
Ticket 和 Attachment 的数据模型是:
export interface Ticket {
id?: string;
description?: string;
assignee?: string;
createdAt?: string;
resolvedAt?: string;
attachments?: Attachment[];
}
export interface Attachment {
name?: string; //contained in result from Endpoint A
id?: string; //contained in result from Endpoint A
relatesTo?: string;
type?: string; //contained in result from Endpoint A
sizeBytes?: string; //contained in result from Endpoint A
hash?: string;
url?: string;
base64Content?: string; //need to fetch this
}
我正在使用以下模板来创建下载文件链接(受到angular-file-saver download base64 file using FileSaver 的极大启发):
<div *ngFor="let attachment of ticket.attachments" class="list-group-item">
<div class="d-flex w-100 justify-content-between">
<a [href]="'data:' + attachment.type + ';base64,' + attachment.base64Content | safeUrl" target="_blank" download="{{ attachment.name }}">{{ attachment.name }}</a>
<small>{{ attachment.sizeBytes | filesize }}</small>
</div>
<small class="mb-1">{{ attachment.type }}</small>
</div>
生成以下 html(请注意仅填充来自端点 A 的数据):
<div _ngcontent-dmp-c28="" class="list-group-item">
<div _ngcontent-dmp-c28="" class="d-flex w-100 justify-content-between">
<a _ngcontent-dmp-c28="" target="_blank" download="test.txt" href="data:text/plain;base64,undefined">test.txt</a>
<small _ngcontent-dmp-c28="">43 B</small>
</div>
<small _ngcontent-dmp-c28="" class="mb-1">text/plain</small>
</div>
(受Angular2 Base64 sanitizing unsafe URL value 启发的网址清理似乎将空base64content 强制为undefined。在清理之前,现在有undefined 的地方将一无所有。
getAttachment 端点只接受attachment.id 作为输入。
我曾尝试以这种方式在Transform data in an Observable 中实施解决方案:
ngOnInit(): void {
console.log(`getting ticket for id ${this.id}`);
this.ticket$ = this.ticketService.getTicket(this.id).pipe(
mergeMap((response: Ticket) => forkJoin([...response.attachments.map((attachment : Attachment) => this.ticketService.getAttachment(attachment.id))])));
}
但无济于事:this.ticket$ 抛出错误“类型 'Observable
【问题讨论】:
标签: angular typescript