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

Add type casting to CSV fields #82

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ Primary wrapper component.
},
age: {
required: true,
label: 'Age'
label: 'Age',
type: Number
}
}"
>
Expand All @@ -101,11 +102,21 @@ Primary wrapper component.

| Prop | Default | Description |
| ------ | ------- | ----------- |
| fields | null | (required) The field names used to map the CSV. |
| fields | see below | (required) The fields used to map the CSV. |
Libertie marked this conversation as resolved.
Show resolved Hide resolved
| text | see below | (optional) Override the default text used in the component. |
| modelValue | N/A | (optional) Binds to the mapped CSV object. |

#### Default text
##### Fields Prop

The fields prop may be a simple array (e.g. `['name', 'age']) or an object with the following properties:

| Prop | Default | Description |
| ------ | ------- | ----------- |
| required | true | (required) The field names used to map the CSV. |
| label | N/A | (required) Override the default text used in the component. |
| type | String | (optional) A primitive object used to cast the field value. |

##### Default Text Prop

```json
{
Expand Down
4 changes: 3 additions & 1 deletion src/components/VueCsvImport.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
key: key,
label: get(val, 'label', val),
required: get(val, 'required', true),
type: get(val, 'type', String),
};
});
}
Expand Down Expand Up @@ -83,11 +84,12 @@

const buildMappedCsv = function () {
let newCsv = VueCsvImportData.fileHasHeaders ? VueCsvImportData.rawCsv : drop(VueCsvImportData.rawCsv);
let typeMap = VueCsvImportData.fields.reduce((a, f) => set(a, f.key, f.type ?? String), {});
Libertie marked this conversation as resolved.
Show resolved Hide resolved

VueCsvImportData.value = map(newCsv, (row) => {
let newRow = {};
forEach(VueCsvImportData.map, (column, field) => {
set(newRow, field, get(row, column));
set(newRow, field, typeMap[field](get(row, column)));
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be a good idea to throw in some kind of error handing to this?
If I had a string in the field Number('abc') -> NaN

Copy link
Author

Choose a reason for hiding this comment

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

Sure thing. We can push a message to VueCsvImportData.errors (e.g. "Invalid data type in row X column Y.").

In terms of fallback, we could use the original string value when a field is otherwise invalid. Would it be overkill to offer a strictTypeCasting option for situations when we actually want to convert invalid fields to null?

Copy link
Contributor

Choose a reason for hiding this comment

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

Pushing to errors and falling back to the original sounds like a good plan 👍
strict option does sound like overkill. imo, I would offload something like this to the server.

Copy link
Author

Choose a reason for hiding this comment

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

This is implemented in the newest commit.

Copy link
Contributor

Choose a reason for hiding this comment

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

🔥 looking good! will have a proper look in the AM 👍

});

return newRow;
Expand Down