Skip to main content

useImport

useImport hook allows you to handle your CSV import logic easily. It uses papaparse under the hood to parse CSV files.

import { useImport } from "@pankod/refine-core";

const { handleChange } = 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",
},
];

With input[type=file]

import React from "react";
import {
useImport,
} from "@pankod/refine-core";

export const PostList: React.FC = () => {
const [total, setTotal] = React.useState(0);
const [processed, setProcessed] = React.useState(0);

const { handleChange } = useImport<IPostFile>({
onFinish: (results) => {
window.alert(JSON.stringify(results));
},
onProgress: ({ totalAmount, processedAmount }) => {
setProcessed(processedAmount);
setTotal(totalAmount);
},
});

return (
<>
<input
type="file"
onChange={(event) => {
if (event.target.files) {
handleChange({
file: event.target.files[0],
});
}
}}
/>
<span>{`${processed}/${total}`}</span>
</>
);
};

interface IPostFile {
title: string;
categoryId: string;
}

tip

The useImport hook contains all the props that the HTML Input element needs (type, accept, onChange) so you can use directly inputProps in your HTML input elements like this

import React from "react";
import {
useImport,
} from "@pankod/refine-core";

export const PostList: React.FC = () => {
const { inputProps } = useImport();
return (
<input
{...inputProps}
/>
);
};

useImport usage

When user clicks the <input> element 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

Return Values

PropertyDescriptionType
inputPropsProps to that you can pass <input /> element props.UseImportInputPropsType
handleChangeProps to handle <input type="file"> element onChangefunction
isLoadingIt can be used to handle the loading status for the Import operationboolean
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

Live StackBlitz Example