Using react formal with my schema statically defined (and reused):
export const AddressSchema = yup.object({
category: string.nullable(),
full_name: string.nullable(),
address1: string.required(),
address2: string.nullable(),
city: string.required().min(2).max(30),
state_code: string.required().min(2).max(2),
postal_code: string.required().min(5).max(13),
country_code: string.default('US').required().min(2).max(3),
default_billing: boolean,
default_shipping: boolean
})
export const ContactSchema = yup.object({
first_name: string.required(),
last_name: string.required(),
email: string.required().email(),
mobile_phone: string.required().phone(),
work_phone: string.phone().nullable(),
home_phone: string.phone().nullable(),
addresses: edges(AddressSchema).min(1)
})
I have a dynamic dataset provided that gives me viable subregions (or states). How can I tack on a dynamic test to state_code inside a render or componentWillMount?
Pseudocode is something like:
render() {
const schema = ContactSchema.clone()
schema.fields.addresses.???.
.test('validState', '${path} is not a valid state',
value => this.props.subregions.includes(value))
}
you can do that ^ however validation is all async so doing a test in render of lifecycle method won't work.
also instead of cloning you can pass arbitrary data to a cast/validation via the context option and access it in the test on this.options.context
Understood that it is async, and thanks for pointing me to context - that looks workable.
My issue is a bit quirky in that I have multiple address subregions (states) to verify which could be in multiple regions (countries).
So state_code verification depends on also knowing the country_code value.
addressRegions is an object that contains information about all addresses (unique set of regions and subregions as lookup values).
So, here's some pseudocode:
country_code: string.default('US').required().min(2).max(3),
state_code: string.required().min(2).max(2)
.test('validState', '${path} is not a valid state',
value => {
console.log('test options', this.options)
const { context, parent: address } = this.options
const addressRegions = context.addressRegions() // how to access context?
const regionCode = this.options.country_code // how to access other field value?
return addressRegions.subregions[ regionCode ].includes(value)
}),
<Form context={{addressRegions}} />
I'm poking around further but any quick advice is appreciated. Thank you.
Follow up to this - got it.
this.options.context gives context.
this.options.parent gives parent object values.
Awesome.
@jquense - i have something strange with this. In my debugger inside the given function, I can see this. But if I console.log(this.options) - I get undefined. Am I authoring this function incorrectly to get the desired this context? (code above updated)
Ugh - can't use arrow functions here if I want this. No problem, just confusion.
Working state validation - dependent on context and other field:
state_code: string.required().min(2).max(2)
.test('validState', '${path} is not a valid state',
function (value) {
if (!value || (value !== null && value.length === 0)) {
return false
}
console.log('test options', this.options)
const { context, parent: address } = this.options
const addressRegions = context.addressRegions()
const regionCode = address.country_code
const result = addressRegions.subregions[ regionCode ].includes(value)
return result
}),
Most helpful comment
Working state validation - dependent on context and other field: