From 650cbc1f011b0fbb8011efa87aca802f19b9fc8c Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 2 May 2023 11:57:18 +0100 Subject: [PATCH] Handle cast as undefineds --- packages/server/src/utilities/csv.ts | 15 ++++++++++++++- packages/server/src/utilities/tests/csv.spec.ts | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/server/src/utilities/csv.ts b/packages/server/src/utilities/csv.ts index 0fab14db45..454f467a9a 100644 --- a/packages/server/src/utilities/csv.ts +++ b/packages/server/src/utilities/csv.ts @@ -1,6 +1,19 @@ import csv from "csvtojson" export async function jsonFromCsvString(csvString: string) { - const result = await csv().fromString(csvString) + const castedWithEmptyStrings = await csv().fromString(csvString) + if (!castedWithEmptyStrings.length) { + return [] + } + + // By default the csvtojson library casts empty values as empty strings. This is causing issues on conversion. + // ignoreEmpty will remove the key completly if empty, so creating this empty object will ensure we return the values with the keys but empty values + const emptyObject = Object.keys(castedWithEmptyStrings[0]).reduce( + (p, v) => ({ ...p, [v]: undefined }), + {} + ) + + let result = await csv({ ignoreEmpty: true }).fromString(csvString) + result = result.map(r => ({ ...emptyObject, ...r })) return result } diff --git a/packages/server/src/utilities/tests/csv.spec.ts b/packages/server/src/utilities/tests/csv.spec.ts index aab5917a9a..9ee0ae4c87 100644 --- a/packages/server/src/utilities/tests/csv.spec.ts +++ b/packages/server/src/utilities/tests/csv.spec.ts @@ -11,6 +11,23 @@ describe("csv", () => { { id: "1", title: "aaa" }, { id: "2", title: "bbb" }, ]) + result.forEach(r => expect(Object.keys(r)).toEqual(["id", "title"])) + }) + + test("empty values are casted as undefined", async () => { + const csvString = + '"id","optional","title"\n1,,"aaa"\n2,"value","bbb"\n3,,"ccc"' + + const result = await jsonFromCsvString(csvString) + + expect(result).toEqual([ + { id: "1", optional: undefined, title: "aaa" }, + { id: "2", optional: "value", title: "bbb" }, + { id: "3", optional: undefined, title: "ccc" }, + ]) + result.forEach(r => + expect(Object.keys(r)).toEqual(["id", "optional", "title"]) + ) }) }) })