ealush / vest

Vest βœ… Declarative validations framework

Home Page:https://vestjs.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

quastion: how to access current object of `arrayOf`.

behzadmehrabi opened this issue Β· comments

Hi, Let's say I have something like this:

enforce(data.items).isArrayOf(
  enforce.shape<VoucherFormItem>({
    subsidiaryAccount: enforce.shape({
      id: enforce.isNumber(),
      code: enforce.isTruthy(),
    }),
    floatAccount: enforce.isValidFloat(); // how can I have access to subsidiaryAccount value of this item in the array here?
    followupNumber: enforce.isNumber(),
    followupDate: enforce.isValid(),
  })
)

how can I have access to subsidiaryAccount value of this item in the array here?
I migrated from yup, so in yup, we had context which you can the parent item of `float account value which is the current object in the array.

P.S: I didn't know where to ask the question since there's no discussion, hope it's alright. :)

Hey @Bezmehrabi, thank you for reaching out :)

When creating enforce's shape validation functions I did not create a straightforward way of accessing context within shape/array validation mainly because it is less commonly used within Vest, and I did not want to add this interface before the need actually came.

I am working on the next version of Vest right now, and I am willing to invest the effort of improving the schema validations features as well.

Would you mind explaining your use cases, and the way you want to be using it? This feedback can help shape (😏 ) the future of Vest.

In the meantime - maybe I can help you find a different way of expressing what you're trying to do. How does isValidFloat intend to use this value?

ok then :), I will explain this part of the application so you will understand why I need this feature.

Problem

{
  subsidiaryAccount: { 
    id: 3,
    code: "11"
    groupTitle: "Cash"
    level1FloatTypeIds: [1, 2]
    level2FloatTypeIds: [4],
    level3FloatTypeIds: [],
    masterTitle: "Master Account Title"
    title: "Subsidiary Account Title"
  }
  // these levels are objects in the real app, but for simplicity of the example, I replace them with an empty string.
  level1: "",
  level2: "",
  level3: ""
}

each subsidiaryAccount gonna have different floatTypeIds for each level. now whether a level should be required or not is based on the value for this level in subsidiaryAccount.
so in our example:

  • level1 is required (because subsidiaryAccount.level1FloatTypeIds is not empty)
  • level2 is the same as level1
  • level3 is not required (because subsidiaryAccount.level3FloatTypeIds is empty)

so, the reason I want this feature is that whether a level is required or not, depends on the subsidiaryAccount of the item.

API

for the API I have no idea, have to think about it.
maybe something like this for custom rules:

isValidFloatLevel({ received, context }, arg1, arg2, arg3) {
   // be able to access the parent in the context. 
}

Thank you for your time and effort :)

Hey @Bezmehrabi, sorry for taking a couple of days to get back to you. I used the time to think about your use case and design an interface that does not require changing how you use enforce today, so it is backwards compatible. Let me know what you think? I believe it covers all your requirements, and adds a few more features such as parent() traversal, the name of the key, and the current index.

Basically, to get the context within your custom rule, simply call enforce.context(). Feel free to comment on the PR: #670

This will be added to the next version of Vest.

Hi, considering backward compatibility, it's great πŸ‘,
parent traversal πŸ‘ŒπŸ‘Œ.
Thanks man.