Reputation: 2237
I have the following functions inside my service:
getFiles(): Observable<File[]> {
const makeFiles = map((response: FileResponse[]): File[] => {
return response.map((fileResponse: FileResponse): File => {
return File.fromResponse(fileResponse);
});
});
return this.httpService.get('/profile/files').pipe(
makeFiles,
shareReplay(),
);
}
getFileUri(filename: string): Observable<SafeUrl> {
return this.httpService.get(`/profile/file/uri/${filename}`).pipe(
mergeMap((uri: string) => this.httpService.get(uri, {}, { useUrlAsItIs: true, responseType: 'arraybuffer' })),
map((fileBuffer: any) => {
const unsafeUrl = URL.createObjectURL(new Blob([fileBuffer], {type: 'application/binary'}));
const safeUrl = this.sanitizer.bypassSecurityTrustUrl(unsafeUrl);
return safeUrl;
})
);
}
As you can see getFiles return Observable of File Array and getFileUri accepts filename (a property of File class) and returns Observable.
What I want to do is, combine these two functions. Meaning, getFiles() should still return Observable<File[]>
and each File in the array should have safeUrl property.
My problem is, I really do not know how to do this complicated task.
Thanks!
Upvotes: 0
Views: 139
Reputation: 96891
If you don't mind running all getFileUri
s in parallel you can use forkJoin
to collect all responses and then update the original File
objects.
import { forkJoin } from 'rxjs';
getFiles().pipe(
mergeMap(files => {
const observables = files.map(file => this.getFileUri(file.filename));
return forkJoin(...observables).pipe(
map((urls: SafeUrl[]) => {
urls.forEach((url, index) => files[index].safeUrl = url);
return files;
}),
);
),
}).subscribe(files => ...);
Upvotes: 1