import * as React from 'react'; import { DataStore, PersistentModel } from '@aws-amplify/datastore'; import { DataStoreBindingProps, DataStoreCollectionProps, DataStoreCollectionResult, DataStoreItemProps, DataStoreItemResult, } from '../primitives/types/datastore'; /** * Perform a collection query against a DataStore model * @internal */ export const useDataStoreCollection = ({ model, criteria, pagination, }: DataStoreCollectionProps): DataStoreCollectionResult => { const [result, setResult] = React.useState>({ items: [], isLoading: false, error: undefined, }); const fetch = () => { setResult({ isLoading: true, items: [] }); const subscription = DataStore.observeQuery( model, criteria, pagination ).subscribe( (snapshot) => setResult({ items: snapshot.items, isLoading: false }), (error: Error) => setResult({ items: [], error, isLoading: false }) ); // Unsubscribe from query updates on unmount if (subscription) { return () => subscription.unsubscribe(); } }; // Fetch on next render cycle // useEffect should only run once here // Ignore exhaustive dependencies rule here by design // eslint-disable-next-line react-hooks/exhaustive-deps React.useEffect(fetch, []); return result; }; /** * Perform a single record query against a DataStore model * @internal */ export const useDataStoreItem = ({ model, id, }: DataStoreItemProps): DataStoreItemResult => { const [item, setItem] = React.useState(); const [isLoading, setLoading] = React.useState(false); const [error, setError] = React.useState(); const fetch = () => { setLoading(true); DataStore.query(model, id) .then(setItem) .catch(setError) .finally(() => setLoading(false)); }; // Fetch on next render cycle // useEffect should only run once here // Ignore exhaustive dependencies rule here by design // eslint-disable-next-line react-hooks/exhaustive-deps React.useEffect(fetch, []); return { error, item, isLoading, }; }; /** * Perform a query against a DataStore model * @internal */ export function useDataStoreBinding( props: DataStoreBindingProps ): DataStoreItemResult; export function useDataStoreBinding( props: DataStoreBindingProps ): DataStoreCollectionResult; export function useDataStoreBinding( props: | DataStoreBindingProps | DataStoreBindingProps ): DataStoreItemResult | DataStoreCollectionResult { return props.type === 'record' ? // eslint-disable-next-line react-hooks/rules-of-hooks useDataStoreItem(props) : // eslint-disable-next-line react-hooks/rules-of-hooks useDataStoreCollection(props); }