0
votes

I need to preload the images in to the browser cache before displaying them. First, I make an http get request to get the json with an array of objects, containing the image details, as well as the image source url. Then I pass the array to the preloadImages method of my images service where i create an observable out of every image, pass the observable to the preloadImage method via mergeMap where I create the new Image() and load it. After that I try to catch the error and return an observable of undefined to keep the stream alive but I fail. I've tried using switchMap to create a new stream and pipe it with mergeMap and catchError but it still fails What should I do?

image.service.ts
  preloadImages(images: any[]) {
return from(images).pipe(
  switchMap(x => {
    const newStream = of(x);
    return newStream.pipe(
      mergeMap(this.preloadImage),
      catchError(e => of(undefined))
    );
  }),

  toArray(),
  );
}

  preloadImage(img): Observable<HTMLImageElement> {
return Observable.create((observer: Observer<HTMLImageElement>) => {
  const image = new Image();
  image.src = img.url;
  image.onload = () => {
    console.log('id: ' + img.id + ' image was loaded');
    observer.next(img);
    observer.complete();
   };
  image.onerror = function (error) {
    observer.error(error);
  };
 });
}

How can I continue the stream if the image url returns a 404? In my subscribe it would be ideal to receive an array of loaded images, and to remove the ones that aren't loaded. Thank you in advance

1
need to see the how you invoke and use preloadImages function, if you call it again then the stream is created again and won't die. need more details about the context. and of course you can use retryWhen operatorFan Cheung

1 Answers

0
votes

this is quite normal rxjs behaviour to finalize the stream when it errors. What you should do is handle the error in the

  .subscribe(
    () => this.onSuccess(),
    error => this.handleError(error),
    () => {
      console.log("finalized.");
    }
  )

In this error handling function (this.handleError(error)) you will actually have to deal with the error and then restart the stream.

Hope this helps.