Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dont wait for whole CSV file to get parsed #230

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,13 @@ Example `data`:
}
```

### onHeadersMapped (_function_)
Callback function that fires when headers have been mapped (when you dont want to wait for onComplete and you just want the mapped headers and the original uploaded file). It returns `selectedHeaderRow` which tells which row was selected as a header row in the previous step, `mappedHeaders` an object that contains the mapping definitions and `originalFile` which is the `File` object representing the original uploaded file without any modifications to it.
When `onHeadersMapped` is defined, `onComplete` callback will not be fired.
```jsx
onHeadersMapped={(selectedHeaderRow, mappedHeaders, originalFile) => console.log(mappedHeaders)}
```

### darkMode (_boolean_, default: `false`)
Toggle between dark mode (`true`) and light mode (`false`).

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "csv-import-react",
"version": "1.0.11",
"version": "1.1.2",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update this to 1.0.12? Or I can just increment the version after this is merged.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ciminelli
Addition of onHeadersMapped is a big update for the library, thats why i incremented the version to 1.1.1 from 1.0.11
And then i fixed a type error that why incremented the version to 1.1.2

"description": "Open-source CSV and XLS/XLSX file importer for React and JavaScript",
"main": "build/index.js",
"module": "build/index.esm.js",
Expand Down
1 change: 1 addition & 0 deletions src/components/CSVImporter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const CSVImporter = forwardRef((importerProps: CSVImporterProps, forwardRef?: an
customStyles,
showDownloadTemplateButton,
skipHeaderRowSelection,
onHeadersMapped,
...props
} = importerProps;
const ref = forwardRef ?? useRef(null);
Expand Down
17 changes: 17 additions & 0 deletions src/importer/features/main/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default function Main(props: CSVImporterProps) {
modalOnCloseTriggered = () => null,
template,
onComplete,
onHeadersMapped,
customStyles,
showDownloadTemplateButton,
skipHeaderRowSelection,
Expand All @@ -40,6 +41,7 @@ export default function Main(props: CSVImporterProps) {
// Error handling
const [initializationError, setInitializationError] = useState<string | null>(null);
const [dataError, setDataError] = useState<string | null>(null);
const [originalFile, setOriginalFile] = useState<File | null>(null);

// File data
const emptyData = {
Expand Down Expand Up @@ -87,6 +89,7 @@ export default function Main(props: CSVImporterProps) {
setColumnMapping({});
setDataError(null);
setStep(StepEnum.Upload);
setOriginalFile(null);
};

const requestClose = () => {
Expand Down Expand Up @@ -118,6 +121,8 @@ export default function Main(props: CSVImporterProps) {
setDataError={setDataError}
onSuccess={async (file: File) => {
setDataError(null);
setOriginalFile(file);

const fileType = file.name.slice(file.name.lastIndexOf(".") + 1);
if (!["csv", "xls", "xlsx"].includes(fileType)) {
setDataError("Only CSV, XLS, and XLSX files can be uploaded");
Expand Down Expand Up @@ -196,6 +201,18 @@ export default function Main(props: CSVImporterProps) {
onSuccess={(columnMapping) => {
setIsSubmitting(true);
setColumnMapping(columnMapping);
if (onHeadersMapped) {
onHeadersMapped(selectedHeaderRow, columnMapping, originalFile)
.then(() => {
setIsSubmitting(false);
goNext();
})
.catch((error) => {
console.error("onHeadersMapped error", error);
setDataError("An error occurred while processing the data");
});
return;
}
Comment on lines +204 to +215
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting this error in testing when onHeadersMapped isn't set: Uncaught TypeError: Cannot read properties of undefined (reading 'then')

Maybe update to use Promise.resolve?

Suggested change
if (onHeadersMapped) {
onHeadersMapped(selectedHeaderRow, columnMapping, originalFile)
.then(() => {
setIsSubmitting(false);
goNext();
})
.catch((error) => {
console.error("onHeadersMapped error", error);
setDataError("An error occurred while processing the data");
});
return;
}
if (onHeadersMapped) {
Promise.resolve(onHeadersMapped(selectedHeaderRow, columnMapping, originalFile))
.then(() => {
setIsSubmitting(false);
goNext();
})
.catch((error) => {
console.error("onHeadersMapped error", error);
setDataError("An error occurred while processing the data");
});
return;
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ciminelli
This code block is executed only when onHeadersMapped is defined

if (onHeadersMapped) {
...
}

If you could upload video of how/where you are getting this error, it would be helpful.


// TODO (client-sdk): Move this type, add other data attributes (i.e. column definitions), and move the data processing to a function
type MappedRow = {
Expand Down
2 changes: 2 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { HTMLAttributes } from "react";
import { TemplateColumnMapping } from "../importer/features/map-columns/types";

type ModalParams = {
isModal?: boolean;
Expand All @@ -14,6 +15,7 @@ export type CSVImporterProps = (HTMLAttributes<HTMLDialogElement> & HTMLAttribut
className?: string;
onComplete?: (data: any) => void;
waitOnComplete?: boolean;
onHeadersMapped?: (selectedHeaderRow: number | null, mappedHeaders: { [index: number]: TemplateColumnMapping }, originalFile: File | null) => Promise<void>;
customStyles?: Record<string, string> | string;
showDownloadTemplateButton?: boolean;
skipHeaderRowSelection?: boolean;
Expand Down