diff --git a/apps/test-app/app/routes/non-object-loader-data.tsx b/apps/test-app/app/routes/non-object-loader-data.tsx new file mode 100644 index 00000000..11a5a97f --- /dev/null +++ b/apps/test-app/app/routes/non-object-loader-data.tsx @@ -0,0 +1,28 @@ +import { json, DataFunctionArgs } from "@remix-run/node"; +import { withZod } from "@remix-validated-form/with-zod"; +import { ValidatedForm } from "remix-validated-form"; +import { zfd } from "zod-form-data"; +import { Input } from "~/components/Input"; +import { SubmitButton } from "~/components/SubmitButton"; + +const validator = withZod( + zfd.formData({ + text1: zfd.text(), + }) +); + +export type LoaderData = string; + +export const loader = (args: DataFunctionArgs) => + json("Hello, world"); + +export default function FrontendValidation() { + return ( + <> + + + + + + ); +} diff --git a/apps/test-app/cypress/integration/default-values.ts b/apps/test-app/cypress/integration/default-values.ts index 0fa8a0b4..7434de44 100644 --- a/apps/test-app/cypress/integration/default-values.ts +++ b/apps/test-app/cypress/integration/default-values.ts @@ -98,4 +98,9 @@ describe("Validation", () => { '"defaultChecked": false' ); }); + + it("should not fail when encountering non-object loader data", () => { + cy.visit("/non-object-loader-data").waitForJs(); + cy.findByLabelText("Text").should("have.value", ""); + }); }); diff --git a/packages/remix-validated-form/src/internal/hooks.ts b/packages/remix-validated-form/src/internal/hooks.ts index 00842eca..fe85b0e8 100644 --- a/packages/remix-validated-form/src/internal/hooks.ts +++ b/packages/remix-validated-form/src/internal/hooks.ts @@ -67,7 +67,10 @@ export const useDefaultValuesFromLoader = ({ // we should use the data from the deepest route. const match = matches .reverse() - .find((match) => match.data && dataKey in match.data); + .find( + (match) => + match.data && typeof match.data === "object" && dataKey in match.data + ); return match?.data[dataKey]; }