Within my model class 'Item', I needed to load two separate images from the backend - a sprite-texture and a shadow-texture. To achieve this, I implemented parallel loading and joining of the textures in my Item so that they could be easily accessed elsewhere.
Initially, I used Base64 to transfer the files to my Angular2 Application, which worked well. However, I now want to switch to using plain blobs. Although Angular2 does not directly support this feature, it is possible to access the private _body property of the response. My goal is for my model class to retrieve the images as HTMLImageElements with the data parsed as a Base64 data URL. In order to generate this data URL from my blobs, I need to utilize FileReader.readAsDataURL(), which operates based on a callback function. I believe I have come up with a way to encapsulate this callback into an Observable, but I am open to corrections if needed.
Currently, I am struggling with chaining my calls correctly to subscribe to a resulting Observable that will produce the desired Item. For example, ItemService.getItem(1).subscribe(item => ...)
The current setup is throwing an error stating that the subscribe method is not defined on the resulting Observable. As someone who is new to RxJS, I would greatly appreciate guidance on how to properly set this up :)
/* implementation in ItemService */
getItem(id:number):Observable<Item> {
return Observable.forkJoin(
this.http.get('/api/items/' + id + '/sprite'),
this.http.get('/api/items/' + id + '/shadow'),
(spriteResponse, shadowResponse) => {
const spriteBlob = new Blob([spriteResponse._body], {type: 'image/png'})
const shadowBlob = new Blob([shadowResponse._body], {type: 'image/png'})
return [spriteBlob, shadowBlob]
})
.flatMap(result => Observable.forkJoin(
ItemService.generateImage(result[0]),
ItemService.generateImage(result[1]),
(spriteImage, shadowImage) => {
const item = new Item()
item.setSprite(spriteImage)
item.setShadow(shadowImage)
return item
})
)
}
static generateImage(data:Blob):Observable<HTMLImageElement> {
const img = new Image()
const reader = new FileReader()
reader.readAsDataURL(data)
return Observable.bindCallback(reader.onloadend, () => {
img.src = reader.result
return img
})
}