Reputation: 402
Hi I'm still experimenting with RxJS & I'm trying for each Observables in an array to retreive the linked image of this Observable like so :
So far I've done this :
public collectAssignements(): Observable<Observable<AssignementEntity>> {
return this.assignementService.get('').pipe(
map((assignments: AssignementEntity[]) => from(assignments.map((assignment) => new AssignementEntity(assignment))))
);
}
public assignements(): Observable<AssignementEntity[]> {
return this.collectAssignements().pipe(
mergeMap((assignment: Observable<AssignementEntity>) => {
return assignment;
}),
map((assignment: AssignementEntity) => {
return assignment;
}),
// here I'd like to use my function getPhoto on assignment.Platform.Logo if there is one (Logo is an Id)
// then set the retreived string (dataUrl) to assignment.Platform.Image
// but I can't figure out how to do that?
toArray()
)
}
To get my Image from my assignment I have to pass the photo Id (here assignment.Platform.Logo) into getPhoto
here that returns an Observable string:
public fileReader(blob: Blob): Observable<string> { // @todo inclure le FileReaderService readAsDataURL
return Observable.create((obs: Observer<string | ArrayBuffer>) => {
const reader = new FileReader();
reader.onerror = err => obs.error(err);
reader.onabort = err => obs.error(err);
reader.onload = () => obs.next(reader.result);
reader.onloadend = () => obs.complete();
return reader.readAsDataURL(blob);
});
}
public getPhoto(id: string, size: string = "min"): Observable<string> {
return this.httpClient.get(`${this.environment.get('webServiceUrl')}/photos/${id}/${this.endpoint.slice(0, -1)}/${size}`, { responseType: "blob" as "json" }).pipe(
mergeMap((blob: Blob) => this.fileReader(blob))
);
}
The get of assignmentService
returns an Observable<Assignment[]>
& the AssignmentEntity
have a Platform
(entity) with a Logo
property (it's an Id with a string). Moreover, the Platform
entity have an Image
property (string) empty by default waiting to be populated with a dataUrl
.
Upvotes: 0
Views: 149
Reputation: 402
After struggling with the RxJS documentation I came up with this solution:
public assignements(): Observable<AssignementEntity[]> {
return this.assignementService.get('').pipe(
map((assignments: AssignementEntity[]) => from(assignments.map((assignment) => new AssignementEntity(assignment)))),
mergeMap((assignment: Observable<AssignementEntity>) => {
return assignment;
}),
map((assignment: AssignementEntity) => {
return assignment;
}),
mergeMap((assignment: AssignementEntity) => { // forEach assignment if it has a Logo then make a request to get the image
return assignment.Platform.Logo !== null ? this.platformService.getPhoto(assignment.PlatformId).pipe(
map((image: string) => {
assignment.Platform.Image = image;
return assignment;
})
) : of(assignment); // return the base assignment if no logo
}),
toArray(), // convert to an array
);
}
Upvotes: 1