Data fetching in CARE
Introduction to useQuery
CARE uses a custom built hook (useQuery
) and a function (request
) to fetch data from and communicate with the backend. These are built on top of fetch.
Basic Usage
Let's see some examples to get to know how to use useQuery
.
export default function Page() {
const { data, loading } = useQuery(routes.users.current);
// `loading` is true if `useQuery` has made a request and is awaiting for response.
if (loading) {
return <Loading />;
}
// `data` is type-safe, inferred from the type provided in the route definition.
return (
<>
<span>Name: {data.name}</span>
<span>Email: {data.email}</span>
</>
);
}
The first argument for useQuery
is the route definition, which contains the resource path, HTTP method, request and response body type.
// example:
const routes = {
users: {
current: {
path: "/api/v1/users/getcurrentuser/",
method: "GET",
TRes: Type<UserModel>(),
}
},
}
Passing query parameters
Now lets say we want to pass some query parameters too maybe (example: GET /example/?name=...
).
export default function Component() {
const { data } = useQuery(MedicineRoutes.search, {
query: {
search: "Hello world!",
type: "GENERIC",
},
});
return <MedicinesList items={data.results} />;
}
Replacing path parameters with a value
Now let's say an API endpoint has a variable in the URL (example: GET /example/{id}/items/
).
export default function Component(props: { consultationId: string }) {
const { data } = useQuery(MedicineRoutes.prescriptions.list, {
pathParams: {
consultation_external_id: props.consultationId,
}
});
return <PrescriptionsList items={data.results} />;
}
Here useQuery
will attempt to replace the {consultation_external_id}
present in the route definition's path with the specified values in the pathParams
.
// route definition example
const MedicineRoutes = {
prescriptions: {
list: {
path: "/api/v1/consultation/{consultation_external_id}/prescriptions/",
method: "GET",
TRes: Type<PaginatedResponse<Prescription>>(),
}
},
}
Performing non-GET requests
Let's say we want to submit a form, here we can make use of request
.
export default function Component(props: { patientId: string }) {
const [data, setData] = useState(...);
const [isProcessing, setIsProcessing] = useState(false);
const handleSubmit = async () => {
if (validate(data)) {
return;
}
setIsProcessing(true);
const { res, errors } = await request(routes.consultation.create, {
pathParams: { patient_id: props.patientId },
body: data,
});
setIsProcessing(false);
}
return (
<form
onSubmit={(e) => {
e.preventDefault();
handleSubmit();
}}
disabled={isProcessing}
>
...
</form>
);
}