Skip to main content
Version: 2.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";

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

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.

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: string;
}

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

API Reference

Properties

KeyDescriptionTypeDefault
resourceNameDefault resource name this button imports to. Inferred from route by default.string
mapDataA 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;
papaparseOptionsCustom Papa Parse options.ParseConfig
batchSizeRequests 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
onFinishCalled with errors and successful responses when all requests are sent.(results: { succeeded: ImportSuccessResult<TVariables, TData>[]; errored: ImportErrorResult<TVariables>[]; }) => void
successNotificationSuccessful Mutation notificationSuccessErrorNotification"Successfully created resource"
errorNotificationUnsuccessful Mutation notificationSuccessErrorNotification"There was an error while creating resource (status code: statusCode)" or "Error when updating resource (status code: statusCode)"
metaDataMetadata query for dataProviderMetaDataQuery{}

Return Values

PropertyDescriptionType
uploadPropsProps to pass to Ant Design's <Upload> component<Upload>
buttonPropsProps to pass to Ant Design's <Button> component<Button>
mutationResultResult of the mutation/mutations of creating imported resourcesUseMutationResult<
{ data: TData },
TError,
{ resource: string; values: TVariables; },
unknown>
) | UseMutationResult<
{ data: TData[]},
TError,
{ resource: string; values: TVariables[]; },
unknown>
)

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