2017-03-12 34 views
5

Wołam MS Graph, aby uzyskać zdjęcie użytkownika:RxJs Obserwowalne - Handle 404 emitując wartość domyślną

// 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(); 

Jednak wielu użytkowników nie ma zdjęcia. W takim przypadku chciałbym utworzyć adres URL obiektu dla domyślnego zdjęcia (może być to jeden z these) i emitować go z Obserwowalnego. Lub nawet wyemituj undefined z Observable, który mogę obsłużyć w przednim panelu, wyświetlając jakiś domyślny obraz.

wiem, że mój połów jest wypalanie, bo widzę to w konsoli przeglądarki:

No photo for user xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx! Returning default... (output redacted)

ja rzeczywiście ciągnąc w wielu różnych bitów danych dla każdego użytkownika, każdy na swój widoczne. Następnie konwertuję każdą z obserwowanych na obietnice, a następnie wykonuję Promise.all() na wszystkich z nich.

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

Problem jest w przypadku 404 do zdjęć użytkownika, cała Promise.all przerywa i nie może pobierać od użytkownika.

Próbowałem złapać błędy w photo$ obserwowalne i emitujące undefined (które planowałem obsłużyć później), ale nie wydaje się robić to, co chcę.

Jak obsługiwać 404 w moim Observable tutaj i emitować coś innego (być może undefined) zamiast zabijać obserwowalne?

Odpowiedz

4

Myślę, że mogłem to rozgryźć. Podpowiedź czai się w konsoli przeglądarki ...

TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

Czytając RxJs documentation on error handling pokazał im robić to, co staram się robić, więc byłem nieco zdezorientowany tym. Ale potem zauważyłem, że w dokumentacji nazywają one funkcję tajemnicy, która, jak zakładałem, zwróciła rzeczywistą pamięć podręczną. Jeśli jednak zwrócą one pewną rzeczywistą pamięć podręczną, to może to wyjaśnić.

Kiedy zmieniłem kod catch do:

 .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); 
      } 
     }) 

... wszystko zaczęło działać.