Entonces, cada vez que recibo una cadena, quiero almacenarla como una matriz. Pero no he tenido suerte hasta ahora, traté de hacerlo con cast y transform. Solo necesito algo de claridad para que las cosas funcionen.
¿Transformar y lanzar es lo mismo? ¿Cómo convertir una cadena en una matriz usando Yup?
const schema = yup.object().shape({ types: yup .array('type must be an array.') .of( yup .string('the array must contains only strings.') .transform(value => typeof value === 'string' || value instanceof 'string' ? [value] : value, ) .matches(/(writer|artist)/, null), ) .min(1, 'Need to provide at least one type') .max(2, 'Can not provide more than two types'), name: yup .string('name must be a string.') .min(3, 'too short'), }); let obj = { name: 'Kentarou Kishima', types: 'artist', } //returns ValidationError obj = schema.cast(obj, { stripUnknown: true }); //trying to just validate results in the same error schema .validate(obj) .then(() => { next(); }) .catch(function (e) { console.log(e); return something; }); ValidationError: los tipos deben ser un tipo de array , pero el valor final fue: null (transmitido desde el valor "artist" )
Editar: arreglé un error tipográfico menor por cierto. Bueno, eliminé la línea de coincidencias y sigue devolviendo el mismo error. Entonces, ahora estoy pensando que, dado que recibe una cadena y no una matriz, cuando ingresa a la función de transformación, buscará los elementos de la matriz para emitir, pero no hay ninguno porque recibió una cadena. Por lo tanto, es muy probable que la función de transformación esté al lado de array() y no dentro de ella.
El código se ve así ahora, pero sigo recibiendo el error con o sin coincidencias ():
.array('types must be an array.') .of( yup .string('the array must contains only strings.') .matches(/(^writer$|^artist$)/) //I improved the regex pattern ) .transform(value => typeof value === 'string' || value instanceof String ? [value] : value, ) .min(1, 'Need to provide at least one type') .max(2, 'Can not provide more than two types'),Para aclarar las cosas, este es el tipo de entrada que espero:
let obj = { name: 'Kentarou Kishima', types: 'artist', //should cast types: ['artist'], //should pass types: ['artist', 'writer'], //should pass types: '', //should reject types: ['something'], //should reject types: ['artist', 'something', 'writer'], //should reject types: ['artist', 'artist'], // should reject, but i will put a test() later on. }Después de jugar con la documentación, encontré la respuesta. En este caso, es suficiente usar la función de ensure() , básicamente tomará todo lo que no sea una matriz y lo colocará en una matriz. Después de eso, la función de matches() rechazará cualquier cosa que no siga el patrón de expresiones regulares.
yup .array('types must be an array.') .of( yup .string('the array must contains only strings.') .matches(/(^writer$|^artist$)/) ) .ensure() .min(1, 'Need to provide at least one type') .max(2, 'Can not provide more than two types'), Editar: solo un descargo de responsabilidad, tal como está con min(1) habilitado, esta propiedad siempre será requerida aunque no haya required() , incluso especificar notRequired() en el objeto no funciona.
Este es un problema conocido en sí https://github.com/jquense/yup/issues/1267
En mi caso, necesito este validador para mis solicitudes POST (todo requerido) y PUT (al menos uno requerido), en las solicitudes POST lo uso tal como está, en las solicitudes PUT agrego dinámicamente las reglas verificando las presentes en el cuerpo.req.
El orden de las operaciones en la propiedad de types está fuera de orden. Sigue:
null . Si realmente desea una matriz de matrices de un solo elemento, puede mantener la transformación, pero querrá mover las matches() encima de la transform() ya que las matrices que resultan de la transform() nunca coincidirán con la regular expresión, por lo que matches() siempre devuelve su null .
const schema = yup.object().shape({ types: yup .array('type must be an array.') .of( yup .string('the array must contains only strings.') .matches(/(writer|artist)/, null) .transform(value => typeof value === 'string' || myVar instanceof 'string' ? [value] : value, ), ) .min(1, 'Need to provide at least one type') .max(2, 'Can not provide more than two types'), name: yup .string('name must be a string.') .min(3, 'too short'), });