How do I use `useEditableTable` with my own custom data fetcher/update logic?

Essentially, I want to use the useEditableTable hook without a resource. I have backend call that can fetch all my models; and I have another one that can update a model
12 Replies
kapa.ai
kapa.ai10mo ago
Hi @derekdoes. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The useEditableTable hook in refine is an extension of the useTable hook and it allows you to implement the edit feature on the Ant Design's Table component with ease. It returns properties that can be used on Ant Design's Table and Form components. Here is a basic usage example of useEditableTable hook:
const { tableProps, formProps } = useEditableTable<TCanvas>();

<Form {...formProps } >
// React nodes here...
</Form>
const { tableProps, formProps } = useEditableTable<TCanvas>();

<Form {...formProps } >
// React nodes here...
</Form>
The useEditableTable hook returns a formProps object that we can pass to Form components in order to handle form actions, loading and displaying success and error messages. It also returns a tableProps object that can be used with the Ant Design's Table component. However, the useTable and useEditableTable hooks in refine are designed to work with a resource which is usually read from the URL. If you want to use these hooks without a resource, you might need to customize the hooks or create your own hooks based on the useTable and useEditableTable hooks. For more information, you can refer to the documentation for useTable (https://refine.dev/docs/api-reference/antd/hooks/table/useTable/) and useEditableTable (https://refine.dev/docs/api-reference/antd/hooks/table/useEditableTable/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10mo ago
<@463543209675718667> kapa.ai is still learning and improving, please let us know how it did by reacting below
conscious-sapphire
conscious-sapphire10mo ago
@kapa.ai can I have useEditableTable use my custom data fetch / update function?
kapa.ai
kapa.ai10mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Yes, you can use your custom data fetch/update function with useEditableTable. However, it's not directly supported by the useEditableTable hook. You would need to use the useCustom hook for fetching data and useUpdate or useUpdateMany hooks for updating data. The useCustom hook is used to send custom query requests using the Tanstack Query advantages. It uses the custom method as the query function from the dataProvider which is passed to <Refine>. Here is the documentation for useCustom (https://refine.dev/docs/api-reference/core/hooks/data/useCustom/). For updating data, you can use the useUpdate or useUpdateMany hooks. These hooks perform the process of updating one or more data respectively. Here are the documentations for useUpdate (https://refine.dev/docs/api-reference/core/hooks/data/useUpdate/) and useUpdateMany (https://refine.dev/docs/api-reference/core/hooks/data/useUpdateMany/). Please note that useCustom, unlike other data hooks, does not invalidate queries and therefore will not update the application state either. If you need to customize the mutation request, use the useCustomMutation (https://refine.dev/docs/api-reference/core/hooks/data/useCustomMutation/) hook instead. Remember to handle the state updates manually when using these hooks with useEditableTable. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10mo ago
<@463543209675718667> kapa.ai is still learning and improving, please let us know how it did by reacting below
conscious-sapphire
conscious-sapphire10mo ago
@kapa.ai so how would I use useCustom and useUpdate with useEditableTable?
kapa.ai
kapa.ai10mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- To use useCustom and useUpdate with useEditableTable, you would need to fetch the data using useCustom and then pass this data to useEditableTable. When the data is edited in the table, you would then use useUpdate to send the updated data back to the server. Here's a simplified example of how you might do this:
import { useCustom, useUpdate, useEditableTable } from "@pankod/refine";

const MyComponent = () => {
const { data, mutate } = useCustom({ url: "/my-endpoint" });
const { mutate: update } = useUpdate();

const { tableProps, formProps } = useEditableTable({
resource: "posts",
initialData: data,
onEdit: (record) => {
update({ resource: "posts", id: record.id, values: record })
.then(() => mutate());
},
});

return (
<Form {...formProps}>
<Table {...tableProps} />
</Form>
);
};
import { useCustom, useUpdate, useEditableTable } from "@pankod/refine";

const MyComponent = () => {
const { data, mutate } = useCustom({ url: "/my-endpoint" });
const { mutate: update } = useUpdate();

const { tableProps, formProps } = useEditableTable({
resource: "posts",
initialData: data,
onEdit: (record) => {
update({ resource: "posts", id: record.id, values: record })
.then(() => mutate());
},
});

return (
<Form {...formProps}>
<Table {...tableProps} />
</Form>
);
};
In this example, useCustom is used to fetch the data from "/my-endpoint". The fetched data is then passed to useEditableTable as initialData. When a row is edited in the table, the onEdit callback is triggered, which uses useUpdate to send the updated data back to the server. After the update is successful, mutate is called to refetch the data. Please note that this is a simplified example and you might need to handle loading and error states, and adjust it according to your needs. For more information, you can refer to the documentation for useCustom (https://refine.dev/docs/api-reference/core/hooks/data/useCustom/), useUpdate (https://refine.dev/docs/api-reference/core/hooks/data/useUpdate/), and useEditableTable (https://refine.dev/docs/api-reference/antd/hooks/table/useEditableTable/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10mo ago
<@463543209675718667> kapa.ai is still learning and improving, please let us know how it did by reacting below
conscious-sapphire
conscious-sapphire10mo ago
@kapa.ai initialData doesn't seem to be on the useEditableTable prop
kapa.ai
kapa.ai10mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- I apologize for the confusion. You're correct, initialData is not a prop for useEditableTable. The useEditableTable hook doesn't directly support custom data fetching or updating. It's designed to work with a resource prop which is usually read from the URL. To use custom data fetching or updating, you would need to create your own hooks or components based on useEditableTable, useCustom, and useUpdate. You would fetch the data using useCustom, store it in a state variable, and then pass this state to your table component. When the data is edited, you would use useUpdate to send the updated data back to the server. Here's a simplified example:
import { useCustom, useUpdate } from "@pankod/refine";
import { Table, Form } from "antd";
import { useState, useEffect } from "react";

const MyComponent = () => {
const { data, isLoading, isError } = useCustom({ url: "/my-endpoint" });
const [tableData, setTableData] = useState([]);
const { mutate: update } = useUpdate();

useEffect(() => {
if (data) {
setTableData(data);
}
}, [data]);

const handleSave = (row) => {
const newData = [...tableData];
const index = newData.findIndex((item) => row.key === item.key);
const item = newData[index];
newData.splice(index, 1, { ...item, ...row });
setTableData(newData);
update({ resource: "posts", id: row.id, values: row });
};

const columns = [
// define your columns here
];

const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const cols = columns.map((col) => ({
...col,
onCell: (record) => ({
record,
inputType: col.dataIndex === 'age' ? 'number' : 'text',
dataIndex: col.dataIndex,
title: col.title,
editing: isEditing(record),
}),
}));

return (
<Form form={form} component={false}>
<Table
components={components}
bordered
dataSource={tableData}
columns={cols}
rowClassName="editable-row"
pagination={{
onChange: cancel,
}}
/>
</Form>
);
};
import { useCustom, useUpdate } from "@pankod/refine";
import { Table, Form } from "antd";
import { useState, useEffect } from "react";

const MyComponent = () => {
const { data, isLoading, isError } = useCustom({ url: "/my-endpoint" });
const [tableData, setTableData] = useState([]);
const { mutate: update } = useUpdate();

useEffect(() => {
if (data) {
setTableData(data);
}
}, [data]);

const handleSave = (row) => {
const newData = [...tableData];
const index = newData.findIndex((item) => row.key === item.key);
const item = newData[index];
newData.splice(index, 1, { ...item, ...row });
setTableData(newData);
update({ resource: "posts", id: row.id, values: row });
};

const columns = [
// define your columns here
];

const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const cols = columns.map((col) => ({
...col,
onCell: (record) => ({
record,
inputType: col.dataIndex === 'age' ? 'number' : 'text',
dataIndex: col.dataIndex,
title: col.title,
editing: isEditing(record),
}),
}));

return (
<Form form={form} component={false}>
<Table
components={components}
bordered
dataSource={tableData}
columns={cols}
rowClassName="editable-row"
pagination={{
onChange: cancel,
}}
/>
</Form>
);
};
In this example, useCustom is used to fetch the data from "/my-endpoint". The fetched data is then stored in the tableData state variable. When a row is edited in the table, the handleSave function is triggered, which uses useUpdate to send the updated data back to the server and updates the tableData state. Please note that this is a simplified example and you might need to handle loading and error states, and adjust it according to your needs. For more information, you can refer to the documentation for useCustom (https://refine.dev/docs/api-reference/core/hooks/data/useCustom/), useUpdate (https://refine.dev/docs/api-reference/core/hooks/data/useUpdate/), and useEditableTable (https://refine.dev/docs/api-reference/antd/hooks/table/useEditableTable/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10mo ago
<@463543209675718667> kapa.ai is still learning and improving, please let us know how it did by reacting below
eastern-cyan
eastern-cyan10mo ago
Hello @derekdoes You can use Ant Design components directly without using the refine useTable hook. You can check the details in the following document. https://ant.design/components/table#components-table-demo-edit-cell
Table - Ant Design
An enterprise-class UI design language and React UI library with a set of high-quality React components, one of best React UI library for enterprises