I'm trying to implement some caching and I have the below method. The catchError
block is causing an error because the return type becomes Observable<Client | Client[]>
. I'm not seeing why it thinks it's not an array of client, or how to fix.
#clients: Client[] = []
#clientsLastModified: string | null = null
index(): Observable<Client[]> {
let headers = new HttpHeaders()
if (this.#clientsLastModified)
headers = headers.set('If-Modified-Since', this.#clientsLastModified)
return this.http.get<IClientDTO[]>('clients', {headers, observe: 'response'}).pipe(
map(x => {
this.#clientsLastModified = x.headers.get('Last-Modified')
if (x.status === HttpStatusCode.Ok && x.body) {
this.#clients = x.body.map(x => new Client(x))
return this.#clients
} else
return of([])
}),
catchError((err: unknown) => {
if (err instanceof HttpErrorResponse && err.status === HttpStatusCode.NotModified)
return this.#clients
return throwError(() => err)
})
)
}
CodePudding user response:
There are two small changes to make to get this corrected:
don't use
of
inside your map. You want the result of your map to return typeClient[]
;of
makes it returnObservable<Client[]>
use
of
insidecatchError
. InsidecatchError
, you should return observable, soof
is needed. The reason no error is shown is because the type is Array, and Array is also a vaildObservableInput
, but will have different behavior. RxJS will convert Array to an observable that emits each item individually (thus the type ends up beingObservable<Client>
instead ofObservable<Client[]>
).
return this.http.get<IClientDTO[]>('clients', {headers, observe: 'response'}).pipe(
map(x => {
this.#clientsLastModified = x.headers.get('Last-Modified')
if (x.status === HttpStatusCode.Ok && x.body) {
this.#clients = x.body.map(x => new Client(x))
return this.#clients
} else
return [] // <-- don't use of
}),
catchError((err: unknown) => {
if (err instanceof HttpErrorResponse && err.status === HttpStatusCode.NotModified)
return of(this.#clients) // <-- use of
return throwError(() => err)
})
)