Distinguish between loading and not found in database queries to find one item
This commit is contained in:
		
							parent
							
								
									a8f3bbac49
								
							
						
					
					
						commit
						f3a73c4d20
					
				| @ -1,6 +1,9 @@ | |||||||
| import { useLiveQuery } from "dexie-react-hooks"; | import { useLiveQuery } from "dexie-react-hooks"; | ||||||
| import { database } from "../model"; | import { database } from "../model"; | ||||||
| 
 | 
 | ||||||
|  | // TODO there may be a case here for reporting errors where relations exist
 | ||||||
|  | //      but some referenced item does not exist in its table, maybe the
 | ||||||
|  | //      return value should be { entries[], errors[] }
 | ||||||
| export function useCategoriesByExpressionId(expression_id: number) { | export function useCategoriesByExpressionId(expression_id: number) { | ||||||
|   return useLiveQuery(() => { |   return useLiveQuery(() => { | ||||||
|     return database.expression_to_category |     return database.expression_to_category | ||||||
|  | |||||||
| @ -1,8 +1,16 @@ | |||||||
| import { useLiveQuery } from "dexie-react-hooks"; | import { useLiveQuery } from "dexie-react-hooks"; | ||||||
| import { database } from "../model"; | import { database, ItemNotFoundError } from "../model"; | ||||||
| 
 | 
 | ||||||
| export function useExpressionById(expression_id: number) { | export function useExpressionById(expression_id: number) { | ||||||
|   return useLiveQuery(() => { |   return useLiveQuery( | ||||||
|     return database.expressions.where({ id: expression_id }).first(); |     () => | ||||||
|   }, [expression_id]); |       database.expressions | ||||||
|  |         .where({ id: expression_id }) | ||||||
|  |         .toArray() | ||||||
|  |         .then((result) => { | ||||||
|  |           if (result.length === 0) return ItemNotFoundError; | ||||||
|  |           return result[0]; | ||||||
|  |         }), | ||||||
|  |     [expression_id] | ||||||
|  |   ); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,9 +1,16 @@ | |||||||
| import { useLiveQuery } from "dexie-react-hooks"; | import { useLiveQuery } from "dexie-react-hooks"; | ||||||
| import { database } from "../model"; | import { database, ItemNotFoundError } from "../model"; | ||||||
| 
 | 
 | ||||||
| export function useExpressionSetById(expression_set_id: number) { | export function useExpressionSetById(expression_set_id: number) { | ||||||
|   return useLiveQuery( |   return useLiveQuery( | ||||||
|     () => database.expression_sets.where({ id: expression_set_id }).first(), |     () => | ||||||
|  |       database.expression_sets | ||||||
|  |         .where({ id: expression_set_id }) | ||||||
|  |         .toArray() | ||||||
|  |         .then((result) => { | ||||||
|  |           if (result.length === 0) return ItemNotFoundError; | ||||||
|  |           return result[0]; | ||||||
|  |         }), | ||||||
|     [expression_set_id] |     [expression_set_id] | ||||||
|   ); |   ); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,9 @@ | |||||||
| import { useLiveQuery } from "dexie-react-hooks"; | import { useLiveQuery } from "dexie-react-hooks"; | ||||||
| import { database } from "../model"; | import { database } from "../model"; | ||||||
| 
 | 
 | ||||||
|  | // TODO there may be a case here for reporting errors where relations exist
 | ||||||
|  | //      but some referenced item does not exist in its table, maybe the
 | ||||||
|  | //      return value should be { entries[], errors[] }
 | ||||||
| export function useExpressionsByExpressionSetId(expression_set_id: number) { | export function useExpressionsByExpressionSetId(expression_set_id: number) { | ||||||
|   return useLiveQuery(() => { |   return useLiveQuery(() => { | ||||||
|     return database.expression_to_expression_set |     return database.expression_to_expression_set | ||||||
|  | |||||||
| @ -14,6 +14,8 @@ export type IndexedExpression = WithId<Expression>; | |||||||
| export type IndexedExpressionSet = WithId<ExpressionSet>; | export type IndexedExpressionSet = WithId<ExpressionSet>; | ||||||
| export type IndexedCategory = WithId<Category>; | export type IndexedCategory = WithId<Category>; | ||||||
| 
 | 
 | ||||||
|  | export const ItemNotFoundError = Symbol(); | ||||||
|  | 
 | ||||||
| class Database extends Dexie { | class Database extends Dexie { | ||||||
|   expressions!: Table<IndexedExpression, number>; |   expressions!: Table<IndexedExpression, number>; | ||||||
|   expression_sets!: Table<IndexedExpressionSet, number>; |   expression_sets!: Table<IndexedExpressionSet, number>; | ||||||
|  | |||||||
| @ -14,8 +14,6 @@ export function ExpressionCardListView() { | |||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
|   if (!expressions) return null; // LOADING
 |   if (!expressions) return null; // LOADING
 | ||||||
|   // TODO query error view?
 |  | ||||||
| 
 |  | ||||||
|   if (!expressions.length) { |   if (!expressions.length) { | ||||||
|     return <ErrorView message="No expression cards yet" />; |     return <ErrorView message="No expression cards yet" />; | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -1,13 +1,16 @@ | |||||||
| import { ExpressionCard } from "../../components"; | import { ExpressionCard } from "../../components"; | ||||||
| import { ExpressionDescription } from "../../components/ExpressionDescription"; | import { ExpressionDescription } from "../../components/ExpressionDescription"; | ||||||
| import { useExpressionById, useQueryExpressionId } from "../../hooks"; | import { useExpressionById, useQueryExpressionId } from "../../hooks"; | ||||||
|  | import { ItemNotFoundError } from "../../model"; | ||||||
|  | import { ErrorView } from "../ErrorView"; | ||||||
| 
 | 
 | ||||||
| export function ExpressionCardView() { | export function ExpressionCardView() { | ||||||
|   const expression_id = useQueryExpressionId(); |   const expression_id = useQueryExpressionId(); | ||||||
|   const expression = useExpressionById(expression_id); |   const expression = useExpressionById(expression_id); | ||||||
| 
 | 
 | ||||||
|   if (expression === undefined) return null; // LOADING
 |   if (expression === undefined) return null; // LOADING
 | ||||||
|   // TODO query error view?
 |   if (expression === ItemNotFoundError) | ||||||
|  |     return <ErrorView message="Expression card not found" />; | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className="page-with-padding content-list scroll"> |     <div className="page-with-padding content-list scroll"> | ||||||
|  | |||||||
| @ -14,9 +14,9 @@ export function ExpressionPracticeView() { | |||||||
|   const expression_set_id = useQueryExpressionSetId(); |   const expression_set_id = useQueryExpressionSetId(); | ||||||
|   const filter_ids = useQueryExpressionIdFilters(); |   const filter_ids = useQueryExpressionIdFilters(); | ||||||
|   const expressions = useExpressionsByExpressionSetId(expression_set_id); |   const expressions = useExpressionsByExpressionSetId(expression_set_id); | ||||||
|  |   // TODO handle errors
 | ||||||
| 
 | 
 | ||||||
|   if (!expressions) return null; // LOADING
 |   if (!expressions) return null; // LOADING
 | ||||||
|   // TODO query error view?
 |  | ||||||
| 
 | 
 | ||||||
|   const filtered_expressions = expressions.filter( |   const filtered_expressions = expressions.filter( | ||||||
|     (expression) => !filter_ids.includes(expression.id!) |     (expression) => !filter_ids.includes(expression.id!) | ||||||
|  | |||||||
| @ -5,8 +5,9 @@ import { | |||||||
|   useQueryExpressionSetId, |   useQueryExpressionSetId, | ||||||
|   useExpressionsByExpressionSetId, |   useExpressionsByExpressionSetId, | ||||||
| } from "../../hooks"; | } from "../../hooks"; | ||||||
| import { IndexedExpressionSet } from "../../model"; | import { IndexedExpressionSet, ItemNotFoundError } from "../../model"; | ||||||
| import { AppPath, AppRouting } from "../../model/routing"; | import { AppPath, AppRouting } from "../../model/routing"; | ||||||
|  | import { ErrorView } from "../ErrorView"; | ||||||
| 
 | 
 | ||||||
| export function ExpressionSetDetailsView() { | export function ExpressionSetDetailsView() { | ||||||
|   const expression_set_id = useQueryExpressionSetId(); |   const expression_set_id = useQueryExpressionSetId(); | ||||||
| @ -14,7 +15,9 @@ export function ExpressionSetDetailsView() { | |||||||
|   const expressions = useExpressionsByExpressionSetId(expression_set_id); |   const expressions = useExpressionsByExpressionSetId(expression_set_id); | ||||||
| 
 | 
 | ||||||
|   if (!expression_set || !expressions) return null; // LOADING
 |   if (!expression_set || !expressions) return null; // LOADING
 | ||||||
|   // TODO query error view?
 |   if (expression_set === ItemNotFoundError) { | ||||||
|  |     return <ErrorView message="Expression set not found" />; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <ExpressionSetDetailsViewImpl |     <ExpressionSetDetailsViewImpl | ||||||
|  | |||||||
| @ -6,8 +6,6 @@ export function ExpressionSetListView() { | |||||||
|   const expression_sets = useAllExpressionSets(); |   const expression_sets = useAllExpressionSets(); | ||||||
| 
 | 
 | ||||||
|   if (!expression_sets) return null; // LOADING
 |   if (!expression_sets) return null; // LOADING
 | ||||||
|   // TODO query error view?
 |  | ||||||
| 
 |  | ||||||
|   if (!expression_sets.length) { |   if (!expression_sets.length) { | ||||||
|     return <ErrorView message="No expression sets found" />; |     return <ErrorView message="No expression sets found" />; | ||||||
|   } |   } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user