I'm using react-query to fetch, and post data from my database on supabase. I created a hook for adding a record using react-query:
export function useCreateSurgeryStage() {
const { mutate: createSurgeryStage, isLoading: isCreating } = useMutation({
mutationFn: ({ surgeryID, stageTitle }) =>
createSurgeryStageById(surgeryID, stageTitle),
onSuccess: () => {
console.log(
// `sent surgery creation request with surgeryID: ${surgeryID} and stageTitle: ${stageTitle}`
`sent surgery creation request...`
);
},
onError: (err) => console.log("ERROR RECEIVED:", err.message),
});
return { isCreating, createSurgeryStage };
}
Here's the mutation function that it calls, which is what actually adds the records into the db:
interface SurgeryStage {
surgeryID: number;
stageTitle: string;
}
export async function createSurgeryStageById(
surgeryID: number,
stageTitle: string
): Promise<SurgeryStage> {
if (!surgeryID || !stageTitle) {
console.log(
`createSurgeryStageById API: didn't correctly receive params: surgeryID:${surgeryID}, stageTitle:${stageTitle}`
);
return;
}
const { data: stage, error } = await supabase.from("Stages").insert([
{
surgeryID,
stageTitle,
},
]);
if (error) throw error;
return stage;
}
This all works exactly as expected: I can add a record into the database using the hook I made with react-query.
But typescript gives me the warning message:
Argument of type '{ surgeryID: any; stageTitle: any; }' is not assignable to parameter of type 'void'.
The warning message is when I try to pass an object into my createSurgeryStage function (which is an alias of the mutate function, from useMutation hook). The handler function:
function handleSurgeryStageInsertion({ stageTitle }) {
const surgeryStage = { surgeryID: channelQuery, stageTitle };
createSurgeryStage(surgeryStage, {
onSettled: reset(),
});
}
You function is returning a value called stage
. But in your function declaration you haven't specified what your function will return. If you don't specify the return type then the return type is considered as void by default. If you don't want to return the value stage
from the function then you can remove the return type or else declare the return type like this:
Some other changes:
data
onError: (err: Error)
interface SurgeryStage {
surgeryID: number;
stageTitle: string;
}
export async function createSurgeryStageById(
surgeryID: number,
stageTitle: string,
): Promise<SurgeryStage | null> { // Added null as return type
if (!surgeryID || !stageTitle) {
console.log(
`createSurgeryStageById API: didn't correctly receive params: surgeryID:${surgeryID}, stageTitle:${stageTitle}`,
);
return null; // explicit null as return type
}
// declare stage separately
const stage: SurgeryStage = {
surgeryID,
stageTitle,
};
const { error } = await supabase.from('Stages').insert([ // the insert query does not return data
stage
]);
if (error) throw new Error(error.message); // throw the error as new error
return stage;
}
export function useCreateSurgeryStage() {
const { mutate: createSurgeryStage, isLoading: isCreating } = useMutation({
mutationFn: ({ surgeryID, stageTitle }: SurgeryStage) =>
createSurgeryStageById(surgeryID, stageTitle),
onSuccess: () => {
console.log(
// `sent surgery creation request with surgeryID: ${surgeryID} and stageTitle: ${stageTitle}`
'sent surgery creation request...',
);
},
onError: (err: Error) => console.log('ERROR RECEIVED:', err.message), // Define type of err
});
return { isCreating, createSurgeryStage };
}
Also your function is an async function. So we have to wrap SurgeryStage inside Promise.