kristianmandrup / schema-to-yup

Schema to Yup validation

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Custom message for type error

lautaroRocha opened this issue · comments

I'm dynamically creating a schema and passing the error messages object as the config param of buildYup

 const config = {
      summary: {
        typeError : "Summary must be a number",
        required: "This field cannot be empty"
      },
      description: {
        required: "This field cannot be empty",
        minLength : "Summary must be at leas 5 characters"
      },
    },
  };

  const yupSchema = buildYup(JSON_RULES, config)

The minLenght and required messages work, but I can't seem to customize the typeError message.
I also tried with type : "..." instead of typeError.

Any thoughts?

I'm not sure there has ever been support for typeError as a config entry. Have you found this in the docs? Is it Yup specific? You are most welcome to help add support for this and I'd be happy to assist you.

I've looked it up and found a stackoverflow Q&A with an example of typeError(msg) chained on the Yup schema entry builder.
It would be simple to add in the YupMixed class so it will be an option for all types (since they all inherit from YupMixed).

So in the YupMixed class, we need to extend the mixedEnabled method to return nå additional "typeError" string item.
This will make it attempt to call a method typeError() which we need to implement on the class. It should simply take this.value.typeError if present and use it as the msg argument for this.base = this.base.typeError(msg)

Thanks for you reply kristian! I'll be looking into that, I'd love to contribute as I'm using this package in my work and it really comes in handy. Expect a PR from me soon!

Added the typeError functionality as described above. Pushed to master and published as 1.12.12. Have not created a unit test for it yet, but it hopefully should work.

I haven't even left the office for the day! great job, i'm amazed of the mainteanence rythm of this package.

Hey @lautaroRocha @kristianmandrup
Wanted to check up on this issue. Were you able to get needed functionality and verify that it works?
Tried implementing in our project the same but could not get it to work.
Perhaps I am supplying config incorrectly somehow?

I've create branch with simple testcase that fails.

ecnaidar@f414697#diff-62c43dd7c0ccc09b50ae751837ffc975c4764ff3cc749cda97476dd92cee77eeR127

Please see this commit: b720535

Note that the functionality has been added but not tested, so it might indeed not work. I suggest you clone the repo and add your test case and play around with it, checking that the typeError method is called and verifying how it currently works.
The apply method is used elsewhere and should call that API method on yup with the arguments coming after (taking from the constraints object.

  typeError() {
    let propTypeError = this.constraints.typeError;
    if (this.isNothing(propTypeError)) return this;
    this.logInfo("typeError", { propTypeError });
    return this.apply(
      "typeError",
      propTypeError
    )
  }

See latest version of the Mixed class here where the typeError method is registered in the mixedEnabled getter which should guarantee that it is called for any concrete type such as string etc.

  get mixedEnabled() {
    return (
      this.mixedConfig.enabled || [
        "oneOf",
        "notOneOf",
        "when",
        "nullable",
        "isType",
        "label",
        "const",
        "refValueFor",
        "typeError",
      ]
    );
  }

Ah, so currently the code expects the typeError to be defined as part of the schema. My bad.

I've amended the code as follows, so that now it reads the typeError info from the config object instead:

  get configErrorEntry() {
    if (!this.config.errors) return {};
    return this.config.errors[this.key] || {};
  }

  typeError() {
    let configTypeError = this.configErrorEntry.typeError;
    if (this.isNothing(configTypeError)) return this;
    this.logInfo("typeError", { configTypeError });
    return this.apply("typeError", configTypeError);
  }

To test it, try the latest master. Usage instructions are included in the Advanced usage on custom logs and error handling

Hey, rebased and check my test, seems that I had to make change to set object as errors and then it worked.
Tried putting either static value or function on errMessages but that did not pass.
Is this errors object a new config and is applied to all field? Why is this being used instead of errMessages?

Sorry for so many questions but checked commit and source and could not understand from a short glance.

I tried to make change so that it uses errMessages config and it seems to work as expected
ecnaidar@c7a84c3#diff-ce65fb75001278c50a298a7e8ecd452f9c8c538c01790cffa09f0cda0b842b1eR379-R384

I see as an upside that the error messages config would be kept uniform and I think it allows also for the functional err. messages provider as well as using existing mechanism to extract error from schema config too.

Is there some potential pitfall that I am missing?
Went ahead and made a PR out of this but we can give it a boot or adjust behaviour further as you see fit

Totally awesome! Much better to keep it simple and uniform by using the errMessages object unless there is a chance of conflicting keys. I think that was my worry. Perhaps it can merge the errMessages and error object, with the error object being merged last, taking precedence if defined. Your thoughts?

No opinion, honestly I am pretty confused about this as I had entirety of 30 minutes in codebase 😅
So I will just lay out questions that directed my thinking

Most confusing is where this new error config property comes from. Could not find any earlier docs and other references in code and seems that it is only used for this specific typeError?
What is the benefits/differences of using this errors over errMessage for this case or in general? Does error object config is being applied somehow for other constraints errors?

errMessage is specified per-field so not sure what kind of key conflict can happen there?
If we are talking about error precedence, from what I could gather that is anyway deferred to yup's implementation.
If it is choosing the right message specced out either in schema or JS config, it should work the same way as every other fields so also not an issue.

UPD: I guess one thing is backwards compatibility but considering this was released very recently, I think it would be OK to amend

OK, sounds legit. I've merged your PR and published it as schema-to-yup@1.12.17

mindblowing turnaround time 🏎️
anyways, thanks for attention on this one, have a nice evening

Seems that you were right regarding conflicts 😑
Started to taking new version into use and seems that adding min or max in initial schema causes type error to default to standard message

I am not sure yet where/how this happens but investigating now.

  • Yup does not seem to care about the order new NumberSchema().typeError("msg").min(0) is the same as new NumberSchema().min(0).typeError("msg")

Hey all, was just curious if there is any progress on this? I've also noticied that min/max causes the standard message to not use the fields label property either