trying to use the convert validation option to cast a number to a string
this works ( casting String to Number ):
joi.validate( "1", joi.number(), { convert : yes } )
while the following returns an error: ValidationError: "value" must be a string
joi.validate( 1, joi.string(), { convert : yes } )
I would expect the second example to cast the number into string and not return an error
Yeah, this is how it should work according to the docs. In reality, the option only converts from strings.
I suspect the immediate fix, is to update the docs.
If you really need the second form, a new .stringify() option could probably be added to the string type, which will then convert the input to a string.
For reference it's already been discussed in https://github.com/hapijs/joi/issues/857. I'm not very fond of reusing the convert flag for this since it's the default, maybe with a new method like you suggested.
thanks, it does seem like reusing convert for this might not be the best idea. stringify() sounds good. Some suggestions for the api:
stringify() without arguments should probably be disallowed since the only reasonable default would be to convert anything using .toString(), which could lead to many unexpected resultsstringify( func ) - would use the provided function for stringification ( the above behaviour could be easily recovered if someone really knows what they are doing and\or is willing to take the risk )stringify( joiSchema ) - would only stringify ( using .toString() ) if then value matches given schema. Example: joi.string().stringify( joi.number() ) would provide what is asked for in this issue and #857.stringify([ joiSchema, ... ]) - as above, but matches agains any of the provided schemas stringify({ schema: s, func: f }) - matches against schema and strigifies using funcstringify([{ schema: s, func: f }, ... ]) - as above, but uses func of the first schema to match in cases 5 and 6, schema could be an array of schemas, which would allow to match against multiple schemas and use one common stratification function. Although the same would be achievable with alternatives ( following the same argument case 4 seems redundant as well ).
I'm inclined to agree with it being an odd usecase. Would you care to share why you need this? Couldn't it be solved with alternatives()?
This was discussed in other issues. I used this workaround today :
const JoiStringConvertible = function (joi) {
return {
base: joi.string(),
name: 'stringConvertible',
coerce (value, state, options) {
function isNumeric (n) {
return !isNaN(parseFloat(n)) && isFinite(n)
}
if (isNumeric(value)) { return value.toString() }
return value
}
}
}
const Joi = require('joi').extend([ JoiStringConvertible ])
const schema = Joi.object().keys({
id: Joi.stringConvertible().optional().allow(null).empty('')
})
// ===
Joi.validate({ id: 123 }, schema) // => ok { id: "123" }
Joi.validate({ id: "abc" }, schema) // => ok { id: "abc" }
Joi is a nice extensible piece of code, thank you
@jeremiegirault thanks for the snippet. worked beautifully. thanks to the creators for making Joi so extensible
I think it's pretty clear we won't do it now, closing.
const JoiStringConvertible = function (joi) {
return {
base: joi.string(),
name: 'stringConvertible',
coerce (value, state, options) {
function isNumeric (n) {
return !isNaN(parseFloat(n)) && isFinite(n)
}
if (isNumeric(value)) { return value.toString() }
return value
}
}
}
const Joi = require('joi').extend([ JoiStringConvertible ])
const schema = Joi.object().keys({
id: Joi.stringConvertible().optional().allow(null).empty('')
})
// ===
Joi.validate({ id: 123 }, schema) // => ok { id: "123" }
Joi.validate({ id: "abc" }, schema) // => ok { id: "abc" }
doesn't work with 19.x
how to update!?
`The following will work for you
result = Joi.extend({
type: 'string',
base: Joi.string(),
coerce: {
from: 'number',
method(value, helpers) {
if (!isNaN(parseFloat(value)) && isFinite(value)) {
return { value: value.toString() }
}
return { value }
}
}
});
result = result.string();`
Most helpful comment
This was discussed in other issues. I used this workaround today :
Joi is a nice extensible piece of code, thank you