diff --git a/js/components/FoodItemSaveBtn.js b/js/components/FoodItemSaveBtn.js index dc92e42..c748c97 100644 --- a/js/components/FoodItemSaveBtn.js +++ b/js/components/FoodItemSaveBtn.js @@ -31,12 +31,12 @@ export default compose( withReplaceRoute, withHandlers({ doSave: ({ saveFoodItem, setLoading, setError, replaceRoute }) => async () => { + setError(null); + setLoading(true); try { - setLoading(true); const { id, name } = await saveFoodItem(); replaceRoute(routeWithTitle(`/foodItem/${id || ''}`, name)); } catch (error) { - console.log(error); // eslint-disable-line setError(error); } finally { setLoading(false); diff --git a/js/enhancers/createFoodItemEnhancers.js b/js/enhancers/createFoodItemEnhancers.js index a99a59c..d0b7ad1 100644 --- a/js/enhancers/createFoodItemEnhancers.js +++ b/js/enhancers/createFoodItemEnhancers.js @@ -6,9 +6,6 @@ import { createFoodItem } from '../apis/FoodItemsApi'; import FoodItemRecord, { createFoodItem as buildFoodItem } from '../records/FoodItemRecord'; import Snackbar from 'react-native-snackbar'; -// should throw an error if not valid -const isFoodItemValid = () => true; - export const withCreateFoodItemState = mapPropsStream(props$ => { return props$.combineLatest(CreateFoodItem$, (props, state) => { const { foodItem, loading, error } = state; @@ -18,13 +15,11 @@ export const withCreateFoodItemState = mapPropsStream(props$ => { const setError = (error: Error) => emitCreateItemState({ ...state, error }); const saveFoodItem = async () => { - if (isFoodItemValid(foodItem)) { + try { // insert new item into db and cast it into FoodItemRecord const newItem = buildFoodItem(await createFoodItem(foodItem)); - Snackbar.show({ - title: foodItem.name + ' added', - }); + Snackbar.show({ title: foodItem.name + ' added' }); // notify food items state of new item emitFoodItemsState(newItem); @@ -34,6 +29,12 @@ export const withCreateFoodItemState = mapPropsStream(props$ => { // allow caller to see what was created return newItem; + } catch (err) { + const error = formatError(err); + + Snackbar.show({ title: error, duration: Snackbar.LENGTH_LONG }); + + throw error; } }; @@ -49,3 +50,30 @@ export const withCreateFoodItemState = mapPropsStream(props$ => { }; }); }); + +function getNameForKey(key) { + switch (key) { + case 'name': + return 'Name'; + case 'placeId': + return 'Place'; + case 'category': + return 'Category'; + case 'quantity': + return 'Quantity'; + case 'latitude': + case 'longitude': + default: + return ''; + } +} + +function formatError({ message } = {}) { + try { + const msgObj = JSON.parse(message); + if (msgObj.missingkeys) { + return `Please fill in ${msgObj.missingkeys.map(getNameForKey).join(', ')}`; + } + } catch (err) {} //eslint-disable-line + return message; +}