useImport
useImport
hook allows you to handle your CSV
import logic easily. It gives you the properties to pass to Ant Design's <Upload>
and <Button>
components and handles the upload logic. It uses papaparse
under the hood to parse CSV
files.
It's return type is compatible with <ImportButton>
. It can also be further customized by using it with Ant Design's <Upload>
Β and <Button>
props.
import { useImport } from "@pankod/refine";
const { uploadProps, buttonProps, mutationResult } = useImport(options);
Usageβ
Assume we have a CSV
file of this contents:
"title","categoryId"
"dummy title 1","3"
"dummy title 2","44"
This file should be parsed as:
[
{
title: "dummy title 1",
categoryId: "3",
},
{
title: "dummy title 2",
categoryId: "44",
}
]
With <ImportButton>
(Recommended)β
import {
List,
Table,
useTable,
useImport,
ImportButton,
} from "@pankod/refine";
export const PostList: React.FC = () => {
const { tableProps } = useTable<IPost>();
const importProps = useImport<IPostFile>();
return (
<List
pageHeaderProps={{
extra: <ImportButton {...importProps} />,
}}
>
<Table {...tableProps} rowKey="id">
<Table.Column dataIndex="id" title="ID" />
<Table.Column dataIndex="title" title="Title" />
<Table.Column dataIndex="status" title="Status" />
</Table>
</List>
);
};
interface IPostFile {
title: string;
categoryId: string;
}
interface IPost {
id: string;
title: string;
status: string;
}
<ImportButton
accepts two properties: buttonProps
and uploadProps
. It just wraps <Button>
component with the <Upload>
component to reduce some boilerplate code.
With Ant Design's <Upload>
and <Button>
Componentsβ
import {
List,
Table,
useTable,
useImport,
Button,
Icons,
Upload,
} from "@pankod/refine";
const { ImportOutlined } = Icons;
export const PostList: React.FC = () => {
const { tableProps } = useTable<IPost>();
const { buttonProps, uploadProps } = useImport<IPostFile>();
return (
<List
pageHeaderProps={{
extra: (
<Upload {...uploadProps}>
<Button icon={<ImportOutlined />} {...buttonProps}>
Import
</Button>
</Upload>
),
}}
>
<Table {...tableProps} rowKey="id">
<Table.Column dataIndex="id" title="ID" />
<Table.Column dataIndex="title" title="Title" />
</Table>
</List>
);
};
This usage is open to further customizations of Ant Design's <Button>
and <Upload>
components.
In both examples, when user clicks the import buttons and selects a CSV
file, useImport
parses the content with papaparse, creates the resources one by one or as batches (depending on the configuration). Which endpoint to create the given resource is inferred from the current route.
Resources are added one by one (useCreate
) or as batches (useCreateMany
) if explicitly configured with batchSize
option. By default, batchSize
is 1.
If batchSize
is more than 1, createMany
method should be implemented in DataProvider
.
Refer to DataProvider documentation for further information about importing the default css. β
Handling Relational Dataβ
In some cases, you might want to change/process the data of CSV
file after parsing. Example cases of this requirement: your data contains relational data and references to data in other places, your backend API requires your data to be sent in a specific format. You can further customize useImport
to achieve this.
Assume this is the CSV
file we want to create resources from:
"title","content","status","categoryId","userId"
"dummy title 1","dummy content 1","rejected","3","8"
"dummy title 2","dummy content 2","draft","44","8"
"dummy title 3","cummy content 3","published","41","10"
Since user
and category
are relational fields, we shouldn't store them as objects. Instead, we should keep only their id
fields in our exported files. And CSV
format doesn't support JSON data, we stored category.id
as categoryId
and user.id
as userId
.
When creating these resources back, we should map it back to our backend API's required format. mapData
option allows us to do this. Here is an example:
const importProps = useImport<IPostFile>({
mapData: (item) => {
return {
title: item.title,
content: item.content,
status: item.status,
category: {
id: item.categoryId,
},
user: {
id: item.userId,
},
};
},
});
interface IPostFile {
title: string;
status: string;
content: string;
categoryId: string;
userId: string;
}
Now, parsed data is mapped to conform our APIs requirements.
API Referenceβ
Propertiesβ
Key | Description | Type | Default |
---|---|---|---|
resourceName | Default resource name this button imports to. Inferred from route by default. | string | |
mapData | A mapping function that runs for every record. Mapped data will be included in the request payload. | (value: any, index?: number, array?: any[], data?: any[][]): any; | |
papaparseOptions | Custom Papa Parse options. | ParseConfig | |
batchSize | Requests batch size. If it is 1, all records are sent one by one. By default, it is Number.MAX_SAFE_INTEGER to send all records in one batch. If it is more than 1, createMany should be implemented on DataProvider. | number | |
onFinish | Called with errors and successful responses when all requests are sent. | (results: { succeeded: ImportSuccessResult<TVariables, TData>[]; errored: ImportErrorResult<TVariables>[]; }) => void | |
successNotification | Successful Mutation notification | SuccessErrorNotification | "Successfully created resource " |
errorNotification | Unsuccessful Mutation notification | SuccessErrorNotification | "There was an error while creating resource (status code: statusCode )" or "Error when updating resource (status code: statusCode )" |
metaData | Metadata query for dataProvider | MetaDataQuery | {} |
Return Valuesβ
Property | Description | Type |
---|---|---|
uploadProps | Props to pass to Ant Design's <Upload> component | <Upload> |
buttonProps | Props to pass to Ant Design's <Button> component | <Button> |
mutationResult | Result of the mutation/mutations of creating imported resources | UseMutationResult< { data: TData }, TError, { resource: string; values: TVariables; }, unknown> ) | UseMutationResult< { data: TData[]}, TError, { resource: string; values: TVariables[]; }, unknown> ) |
Type Parametersβ
Property | Desription | Default |
---|---|---|
TItem | Interface of parsed csv data | any |
TData | Result type of the data query type that extends BaseRecord | BaseRecord |
TError | Custom error object that extends HttpError | HttpError |
TVariables | Values for mutation function | any |