Ok, esta es una pregunta extraña que parece que no puedo entender bien.
Tengo un objeto grande y complejo para enviar a un servidor. Después de varios intentos, intenté usar Joi para validar el esquema y me gustó, pero devolver los errores a las entradas es una pesadilla.
El cuerpo se subdivide en 5 secciones, y cada subsección contiene entre 10 y 30 campos, algunos de los cuales son string[] , interface[] , number[] o interfaces anidadas generales.
Intenté escribir mi propia validación personalizada y la complejidad se salió de control.
(Sé que algunos de ustedes están pensando "su esquema es demasiado complejo" y tienen razón, pero no es algo que pueda cambiar en este momento. Clientes, bla, bla).
El problema: Joi.validate(myBody) me da un montón de errores en el siguiente formato:
[ // <- error.details { context: {}, message: "X is not allowed to be empty", path:["path","to","property"], // <- this is the key type: "" } ]¿Cómo puedo mapear error.details para crear un nuevo objeto de validación que luego pueda usar para los elementos del formulario?
Por ejemplo:
path = ["path","to","property"] // -> map over to create let newObj = { path:{ to: { property: "" } } }Espero que esto tenga sentido.
Quiero tomar una serie de errores de validación y convertirlos en un objeto de validación que coincida con el objeto inicial
El enfoque más simple, en mi opinión, sería usar reduce para revertir la creación del objeto a partir de la matriz
["path","to","property"].reduceRight((prev, current) => { const obj = {}; obj[current] = prev return obj; }, ""); Esto creará el objeto como se describe en la pregunta original. Debe usar reduceRight en lugar de reduce para crear primero el nodo de hoja; de lo contrario, tendrá que intentar atravesar el gráfico cada vez que agregue un nuevo nodo y debe manejar la configuración del nodo de hoja para que sea una cadena en lugar de un objeto. .
Extrapolando lo que está tratando de lograr, asumo un par de cosas:
Podemos ampliar lo anterior con la solución de combinación profunda desde aquí para crear un objeto para devolver. El código para eso se vería así:
const errors = [ // <- error.details { context: {}, message: "X is not allowed to be empty", path:["path","to","property"], // <- this is the key type: "" }, { context: {}, message: "X has to be greater than 0", path:["path","to","another", "property"], // <- this is the key type: "" } ] function isObject(item) { return (item && typeof item === 'object' && !Array.isArray(item)); } function mergeDeep(target, ...sources) { if (!sources.length) return target; const source = sources.shift(); if (isObject(target) && isObject(source)) { for (const key in source) { if (isObject(source[key])) { if (!target[key]) Object.assign(target, { [key]: {} }); mergeDeep(target[key], source[key]); } else { Object.assign(target, { [key]: source[key] }); } } } return mergeDeep(target, ...sources); } errors.map((e) => e.path.reduceRight((prev, current) => { const obj = {}; obj[current] = prev return obj; }, e.message)).reduce((previous, current) => mergeDeep(previous, current), {}) El resultado de ejecutar errors a través de él sería:
{ path: { to: { property: 'X is not allowed to be empty', another: { property: 'X has to be greater than 0' } } } }Se utiliza el enunciado del problema
Quiero tomar una serie de errores de validación y convertirlos en un objeto de validación que coincida con el objeto inicial
Dado : una matriz de cadenas (cada una de las cuales es un accesorio)
Resultado esperado : un objeto estructurado basado en la matriz
Fragmento de código
// given an array of props // starting at root-level & ending at the leaf const pList = ['root', 'lev1', 'lev2', 'propName']; // method to transform array into an object const transformToObj = arr => ( arr .reverse() .reduce( (fin, itm) => ({ [itm]: fin ? {...fin} : '' }), false ) ); // test with given array console.log(transformToObj(pList)); // test with user-input array (comma-separated) console.log(transformToObj([...( (prompt('Enter comma-separated path like a,b,c,d')) .split(',') .map(x => x.trim()) )]));Explicación
.reduce para iterar