RxJs Observable - 404 handle emitting a default value

I call MS Graph to get a user photo:

// lets get the photo itself let photo$ = this.graph.get$(`users/${id}/photo/$value`, ResponseContentType.Blob) .map(resp => { return new Blob([resp.blob()], { type: resp.headers.get['Content-Type']}); }) .map(photo => { let urlCreator = window.URL; return this.sanitizer .bypassSecurityTrustUrl(urlCreator.createObjectURL(photo)); }) .catch(function (e) { if(e.status === 404) { // no photo for this user! console.log(`No photo for user ${id}! Returning default...`); return undefined; } }) .toPromise(); 

However, many users do not have a photograph. In this case, what I would like to do is create an object url for some default photo (one of these maybe) and emit it from Observable, Or even just release undefined from Observable, which I can handle in the interface showing the default image.

I know that my catch shoots because I see this in the browser console:

There is no photo for user xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx! return to default ... (output edited)

I actually collect many different bits of data for each user, each in its own Observable. Then I convert each of them Observable to Promises, and then do a Promise.all() for all of them.

  // let pull all of this together to form a ConcreteUser return Promise.all([photo$, ...]) .then(values => { const photo = values[0]; ... 

The problem is 404 for the user's photo, the whole of Promise.all is interrupted, and I cannot get the user.

I tried to catch errors in photo$ observable and emitting undefined (which I planned to handle later), but it doesn't seem to do what I want.

How do I handle 404s in my Observable here and emit something else (possibly undefined ) instead of killing observables?

+5
source share
1 answer

I think I may have figured this out. There was a hint in the browser console ...

TypeError: you specified 'undefined' where the stream was expected. You can provide observation, promise, array, or iterability.

Reading the RxJs documentation on error handling showed that they were doing what I was trying to do, so I was a bit confused about this. But then I noticed that in the documentation they call the secret function getCachedVersion() , which I assumed returned the actual cached thing. However, if they instead returned Observable.of() some actual cached thing, then this could explain it.

When I changed my catch code to:

  .catch(function (e) { if(e.status === 404) { // no photo for this user! console.log(`No photo for user ${id}! Returning default...`); return Observable.of(undefined); } }) 

... it all started.

+4
source

Source: https://habr.com/ru/post/1265359/


All Articles