question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

partial() doesn't work

See original GitHub issue

I use userUpdateSchema to make all fields optional and pass undefined password field but keep getting Should be at least 3 characters for password field. The schemas are bellow:

export const userLoginSchema = z.object({
  email: z.string().email(),
  password: z.string().min(3).max(20), // I send undefined for this field
});

export const userRegisterSchema = userLoginSchema.extend({
  name: z.string().min(3).max(15),
  username: z.string().min(3).max(15),
});

export const userUpdateSchema = userRegisterSchema
  .extend({
    avatar: isBrowser() ? z.instanceof(FileList) : z.any(),
  })
  .omit({ email: true })
  .partial(); // make all fields optional

...

const Settings: React.FC<Props> = ({ user }) => {

  const { register, handleSubmit, formState, watch, getValues } = useForm({
    resolver: zodResolver(userUpdateSchema), // use this schema
    defaultValues: {
      username: user.username,
      name: user.name,
      avatar: user.image,
      password: undefined, // like this, just submit initial values
    },
  });

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6

github_iconTop GitHub Comments

1reaction
scotttrinhcommented, Nov 30, 2021

@nemanjam

Zod is usable with React, but I think it takes some understanding of how it (and other runtime type systems like it) work. For forms, the concept of “required” or “optional” typically refers to having a non-empty value, where TypeScript considers "" to be a string and thus qualifies as a required value, as does Zod.

For your use case, without knowing much about useForm (which is from React Hook Form, not part of React), I can only give a little guidance, but I’m not a user of that particular library. If your schema needs to allow for the empty string, we don’t currently have a shortcut for allowing "" for any key in an object similar to partial. Looking at the docs for React Hook Form, I think you’ll need to manually apply .or(z.literal("")) to each key to allow them to be submitted with an empty string. You could also do a little bit of preprocessing to convert any empty strings into undefined so you can use optional:

Updated the CodeSandbox as well

const emptyStringToUndefined = (data: unknown) =>
  Object.entries(data as Record<string, string>).reduce(
    (acc, [key, value]) => ({
      ...acc,
      [key]: value === "" ? undefined : value
    }),
    {}
  );

export const userUpdateSchema = z.preprocess(
  emptyStringToUndefined,
  userRegisterSchema.extend({ avatar: z.any() }).omit({ email: true }).partial()
);
0reactions
scotttrinhcommented, Dec 10, 2021

@nemanjam

it is also relevant that library has elegant api for very common use case such is usage with the most popular React form library because a lot of people will try to use it for such purpose and have hard time with it.

I absolutely agree that easing integration with things like react-hook-form is very important, but we have to be careful about what zod provides to ensure that it is:

  1. Close to the stated goal of being a runtime representation of TypeScript’s type system
  2. Flexible for use in as many contexts and use cases as we can

To that end optional is specifically intended to match TypeScript’s concept of “optional”.

Up to this point, we’ve really put the requirement on the library to find ways to integrate with zod, but I hope that we can be more proactive and helpful with troubleshooting and contributing to these projects. I don’t think there is much zod “core” needs to do, but there is a layer of abstraction between zod the runtime type-system and validation layers for things like forms, JSON, query strings, CSV parsing, etc. and I think we can try to be more actively helpful in those areas.

Having said that, for now, this is a problem that is best served by addressing with the react-hook-form team. I’m happy to help and contribute to that project to help smooth over bumps like this!

Maybe optional() and partial() could accept argument like optional([undefined, null, ‘’]).

Other than partial, your suggestion is exactly what z.union does, so if that works for your purposes, feel free to make yourself a little utility schema:

export const stringyNillable = z.union([z.undefined(), z.null(), z.literal(''), z.string()]);

stringyNillable.parse(undefined); // passes
stringyNillable.parse(null); // passes
stringyNillable.parse(""); // passes
stringyNillable.parse("a non empty string"); // passes

You could make this a bit more generic and use it to create a partial helper, too.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Python partial function doesn't execute - Stack Overflow
map() won't recursively call objects; only the outermost object is called. In Python 2, the code now works: >>> map(lambda a, c: myzebra....
Read more >
Partial Functions in Python - GeeksforGeeks
Partial functions allow us to fix a certain number of arguments of a function ... And g() just takes a single argument i.e....
Read more >
functools — Higher-order functions and operations on callable ...
This means it will not work with some types, such as metaclasses (since the ... The partial() is used for partial function application...
Read more >
not working with my partial view mvc grid — DataTables forums
I've tried adding the code below to both the index page and directly on the partial view page. neither works. what am i...
Read more >
purescript-partial - GitHub
Utilities for working with partial functions. Contribute to purescript/purescript-partial development by creating an account on GitHub.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found