diff --git a/frontend/src/metabase-lib/v1/parameters/utils/parameter-parsing.ts b/frontend/src/metabase-lib/v1/parameters/utils/parameter-parsing.ts index c7e31d9d7e5b18d6d27f87f1e86b0a4a6a6a8f23..ba53aa958846d7a8e1a3bdb0ebb5f60b34c5e25c 100644 --- a/frontend/src/metabase-lib/v1/parameters/utils/parameter-parsing.ts +++ b/frontend/src/metabase-lib/v1/parameters/utils/parameter-parsing.ts @@ -60,26 +60,27 @@ export function parseParameterValue(value: any, parameter: Parameter) { function parseParameterValueForNumber(value: string | string[]) { if (Array.isArray(value)) { - return value.map(number => parseFloat(number)); + const numbers = value.map(number => parseFloat(number)); + return numbers.every(number => !isNaN(number)) ? numbers : null; } // something like "1,2,3", "1, 2, 3", ",,,1,2, 3" const splitValues = value.split(",").filter(item => item.trim() !== ""); - if (splitValues.length === 0) { - return; + return null; } - const isNumberList = - splitValues.length > 1 && - splitValues.every(item => !isNaN(parseFloat(item))); + if (splitValues.length > 1) { + const numbers = splitValues.map(number => parseFloat(number)); + if (numbers.every(number => !isNaN(number))) { + return numbers.join(","); + } - if (isNumberList) { - // "1, 2, 3" will be tranformed into "1,2,3" for later use - return splitValues.map(item => parseFloat(item)).join(","); + return null; } - return parseFloat(value); + const number = parseFloat(value); + return isNaN(number) ? null : number; } function parseParameterValueForFields( @@ -108,6 +109,7 @@ function normalizeParameterValueForWidget( ) { const fieldType = getParameterType(parameter); if ( + value != null && fieldType !== "date" && fieldType !== "temporal-unit" && !Array.isArray(value) diff --git a/frontend/src/metabase-lib/v1/parameters/utils/parameter-parsing.unit.spec.js b/frontend/src/metabase-lib/v1/parameters/utils/parameter-parsing.unit.spec.js index a7fe50aa2209a0d35d6504ef99874a6dd30e991e..287c47da11e465213130d50d49b4a8c4cadbaa98 100644 --- a/frontend/src/metabase-lib/v1/parameters/utils/parameter-parsing.unit.spec.js +++ b/frontend/src/metabase-lib/v1/parameters/utils/parameter-parsing.unit.spec.js @@ -294,6 +294,29 @@ describe("parameters/utils/parameter-values", () => { ); }); + it.each([ + { value: "", expectedValue: null }, + { value: "abc", expectedValue: null }, + { value: "123", expectedValue: [123] }, + { value: "123abc", expectedValue: [123] }, + { value: ["123"], expectedValue: [123] }, + { value: ["123", "234"], expectedValue: [123, 234] }, + { value: ["123", "abc"], expectedValue: null }, + { value: ["123", "234abc"], expectedValue: [123, 234] }, + { value: "123,234", expectedValue: ["123,234"] }, + { value: "123,abc", expectedValue: null }, + { value: "123,234abc", expectedValue: ["123,234"] }, + ])( + "should parse number parameter value $value", + ({ value, expectedValue }) => { + const parameter = createMockParameter({ type: "number/=" }); + const queryParams = { [parameter.slug]: value }; + expect( + getParameterValueFromQueryParams(parameter, queryParams), + ).toEqual(expectedValue); + }, + ); + describe("last used param value", () => { it("should use query parameter over last used param value", () => { expect( @@ -349,16 +372,14 @@ describe("parameters/utils/parameter-values", () => { ]); }); - it("should return undefined when list is not formatted properly", () => { - expect(runGetParameterValueFromQueryParams(",,,")).toEqual([ - undefined, - ]); - expect(runGetParameterValueFromQueryParams(" ")).toEqual([undefined]); + it("should return `null` when list is not formatted properly", () => { + expect(runGetParameterValueFromQueryParams(",,,")).toEqual(null); + expect(runGetParameterValueFromQueryParams(" ")).toEqual(null); }); - it("should return first parseable float if value includes non-numeric characters", () => { - expect(runGetParameterValueFromQueryParams("1,a,3,")).toEqual([1]); - expect(runGetParameterValueFromQueryParams("1a,b,3,")).toEqual([1]); + it("should return `null` if value includes non-numeric characters", () => { + expect(runGetParameterValueFromQueryParams("1,a,3,")).toEqual(null); + expect(runGetParameterValueFromQueryParams("1a,b,3,")).toEqual(null); }); }); });