From e77efcecb0daf94d58163204d734eb9366ec5b89 Mon Sep 17 00:00:00 2001 From: Morgan Ney Date: Mon, 11 Dec 2023 18:29:22 -0600 Subject: [PATCH] fix: valid json for empty favorite deletes. (#135) --- packages/api/src/handlers/favorite.ts | 15 +++++++++++---- packages/api/src/queries/favorite.ts | 7 +++++-- packages/api/src/types.ts | 8 +------- packages/common/src/types/favorites.ts | 8 +++++++- packages/ui/src/modules/favorites/api/delete.ts | 3 ++- .../modules/favorites/components/favoriteStop.tsx | 7 +++++-- .../modules/favorites/components/favorites.tsx | 7 +++++-- 7 files changed, 36 insertions(+), 19 deletions(-) diff --git a/packages/api/src/handlers/favorite.ts b/packages/api/src/handlers/favorite.ts index 6722718..f7e07f5 100644 --- a/packages/api/src/handlers/favorite.ts +++ b/packages/api/src/handlers/favorite.ts @@ -8,8 +8,11 @@ import { } from '../queries/favorite.js' import type { Request, Response } from 'express' -import type { Favorite, RiderFavoriteItem } from '@busmap/common/types/favorites' -import type { RiderFavorite } from '../types.js' +import type { + Favorite, + RiderFavorite, + RiderFavoriteItem +} from '@busmap/common/types/favorites' import type { HttpError } from 'http-errors' const debug = makeDebug('busmap') @@ -57,8 +60,12 @@ const favorite = { const removed = await removeRiderFavorite(req.session.userId, favorite) debug('removed rider favorite', removed) - - return res.json(removed[0]) + /** + * Guard against returning `undefined` + * if `removed` is an empty array because + * no rows were actually deleted. + */ + return res.json(removed[0] ?? null) } catch (err) { return res.status(500).json(new errors.InternalServerError()) } diff --git a/packages/api/src/queries/favorite.ts b/packages/api/src/queries/favorite.ts index 58b2879..53cad45 100644 --- a/packages/api/src/queries/favorite.ts +++ b/packages/api/src/queries/favorite.ts @@ -1,7 +1,10 @@ import { sql } from '../db.js' -import type { Favorite, RiderFavoriteRow } from '@busmap/common/types/favorites' -import type { RiderFavorite } from '../types.js' +import type { + Favorite, + RiderFavorite, + RiderFavoriteRow +} from '@busmap/common/types/favorites' const addRiderFavorite = async (favorite: Favorite, userId: number) => { const { agency, route, stop } = favorite diff --git a/packages/api/src/types.ts b/packages/api/src/types.ts index 1d21957..4bbb349 100644 --- a/packages/api/src/types.ts +++ b/packages/api/src/types.ts @@ -1,11 +1,5 @@ -interface RiderFavorite { - rider: number - favorite: number - rank: number - created: string -} interface AddRiderFavorite { created: string } -export type { RiderFavorite, AddRiderFavorite } +export type { AddRiderFavorite } diff --git a/packages/common/src/types/favorites.ts b/packages/common/src/types/favorites.ts index 2562ce0..66cd028 100644 --- a/packages/common/src/types/favorites.ts +++ b/packages/common/src/types/favorites.ts @@ -13,6 +13,12 @@ interface Favorite { // API models +interface RiderFavorite { + rider: number + favorite: number + rank: number + created: string +} interface RiderFavoriteRow { created: string rank: number @@ -29,4 +35,4 @@ interface RiderFavoriteItem { favorite: Favorite } -export type { RouteMeta, Favorite, RiderFavoriteRow, RiderFavoriteItem } +export type { RouteMeta, Favorite, RiderFavorite, RiderFavoriteRow, RiderFavoriteItem } diff --git a/packages/ui/src/modules/favorites/api/delete.ts b/packages/ui/src/modules/favorites/api/delete.ts index 3424bc9..fc9401c 100644 --- a/packages/ui/src/modules/favorites/api/delete.ts +++ b/packages/ui/src/modules/favorites/api/delete.ts @@ -1,6 +1,7 @@ import { transport } from '@core/api/transport.js' import { errors } from '@core/api/errors.js' +import type { RiderFavorite } from '@busmap/common/types/favorites' import type { Favorite } from '../types.js' const remove = async (favorite: Favorite) => { @@ -8,7 +9,7 @@ const remove = async (favorite: Favorite) => { throw errors.create('GET', 400, 'Bad Request') } - const resp = await transport.fetch('/favorite/remove', { + const resp = await transport.fetch('/favorite/remove', { method: 'DELETE', body: JSON.stringify({ favorite diff --git a/packages/ui/src/modules/favorites/components/favoriteStop.tsx b/packages/ui/src/modules/favorites/components/favoriteStop.tsx index 71e0daf..399fcf5 100644 --- a/packages/ui/src/modules/favorites/components/favoriteStop.tsx +++ b/packages/ui/src/modules/favorites/components/favoriteStop.tsx @@ -68,8 +68,11 @@ const FavoriteStop: FC = ({ selection, size = 'medium' }) => if (user) { try { - await removal.mutateAsync(favorite) - toast({ type: 'info', message: 'Favorite removed.' }) + const removed = await removal.mutateAsync(favorite) + + if (removed) { + toast({ type: 'info', message: 'Favorite removed.' }) + } } catch (err) { toast({ type: 'error', message: 'Error removing favorite.' }) } diff --git a/packages/ui/src/modules/favorites/components/favorites.tsx b/packages/ui/src/modules/favorites/components/favorites.tsx index df11dd8..f3e9aeb 100644 --- a/packages/ui/src/modules/favorites/components/favorites.tsx +++ b/packages/ui/src/modules/favorites/components/favorites.tsx @@ -101,8 +101,11 @@ const Favorites = memo(function Favorites() { if (user) { try { - await remove(fav) - toast({ type: 'info', message: 'Favorite removed.' }) + const removed = await remove(fav) + + if (removed) { + toast({ type: 'info', message: 'Favorite removed.' }) + } } catch (err) { toast({ type: 'error', message: 'Error removing favorite.' }) }