I'm having problems catching errors of my observable. I'm using angular 7 and rxjs 6.3.3.
Context
I'm writing a webshop where I store the shopping cart in my local storage. Some events (fe. loading the shopping cart overview) needs to have the most updated version of the shopping cart. In this case I take the ID of the shopping cart in my localstorage and contact the API to get the most recent version. After this request I will update the localstorage. Until now, this works fine. Sometimes it could be that the shopping cart in my local storage doesn't exists anymore in the database and when contacting the API I receive a 404 not found. What I'm trying to achieve is that my webshop will catch this 404 and then create a new shoppingcart.
Framework code
Since we are using a framework for multiple clients we wrote a lib with general actions. The lib is installed on the angular website.
The code to get a shopping cart:
getShoppingCart(userId: number, id: number): Observable<ShoppingCart> {
return this.get(`api/users/${userId}/shoppingcarts/${id}`);
}
The code to create a new shopping cart:
createShoppingCart(command: CreateShoppingCartCommand): Observable<ShoppingCart> {
return this.post(`api/users/${command.userId}/shoppingcarts`, command);
}
Application code
// write to local storage
get ActiveShoppingCart(): ShoppingCart {
const value: string = localStorage.getItem('shoppingCart');
if (!value) {
return null;
}
const shoppingCart: ShoppingCart = JSON.parse(value);
return shoppingCart;
}
// get from local storage
set ActiveShoppingCart(shoppingCart: ShoppingCart) {
localStorage.setItem('shoppingCart', JSON.stringify(shoppingCart));
this.notifyObservers();
}
// this method will return the most up to date shopping cart
getUpdatedShoppingCart(): Observable<ShoppingCart> {
const activeShoppingCart: ShoppingCart = this.ActiveShoppingCart;
if (activeShoppingCart) {
// if the shopping cart is saved in the local storage, use this one
// if I receive a 404 error, catch it, remove it from localstorage and execute this method again
return this.libShoppingCartService.getShoppingCart(activeShoppingCart.userId, activeShoppingCart.id).pipe(
catchError((_: any) => {
this.ActiveShoppingCart = null;
return this.getActiveShoppingCart();
})
);
}
// code to create a new shopping cart and save it to local storage, this works fine
}
Issue
The catchError doesn't actually catch this http 404 error. I'm looking for a way how I can catch this. I'd rather fix this in my application instead of the framework code, but if there is no other option I'm glad to do it.
I'm not looking for someone exactly telling me what to do but if someone can give me some indication what is wrong in my code, that would be great! :)
Extra info
In my console I receive the following errors (which makes sense)
GET https://apiurl/api/users/28/shoppingcarts/87 404
ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. at subscribeTo (subscribeTo.js:41) at subscribeToResult (subscribeToResult.js:11) at CatchSubscriber.push../node_modules/rxjs/_esm5/internal/operators/catchError.js.CatchSubscriber.error (catchError.js:43) at XMLHttpRequest.onLoad (http.js:1547) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421) at Object.onInvokeTask (core.js:14182) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188) at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:496) at invokeTask (zone.js:1540)
this.getActiveShoppingCart()doesn't return anything ifactiveShoppingCart === falsebutcatchErroralways requires an Observable.catchErrorsomewhere where you're not returning anything. It's not about throwing errors.