Skip to main content
Version: 3.xx.xx

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-antd";

const { uploadProps, buttonProps, mutationResult } = useImport(options);

Usage​

Assume we have a CSV file of this contents:

dummy.csv
"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",
}
]
import {
List,
Table,
useTable,
useImport,
ImportButton,
} from "@pankod/refine-antd";

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: number;
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-antd";

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.

caution

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:

dummy.csv
"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: number;
}

Now, parsed data is mapped to conform our APIs requirements.

API Reference​

Properties​

Return Values​

Type Parameters​

PropertyDesriptionDefault
TItemInterface of parsed csv dataany
TDataResult type of the data query type that extends BaseRecordBaseRecord
TErrorCustom error object that extends HttpErrorHttpError
TVariablesValues for mutation functionany