DEV Community

Heiker
Heiker

Posted on Edited on Originally published at vonheikemen.github.io

CÃģmo un funtor aplicativo puede ayudarnos a validar formularios

Lo que haremos en esta ocasiÃģn serÃĄ 'jugar' con este concepto de funtor aplicativo, específicamente lo vamos a usar para validar datos que un usuario ha colocado en un formulario.

Si no saben quÃĐ es un funtor aplicativo tal vez quieran un breve resumen... pero no puedo hacer eso hoy. AÚn no tengo un dominio del tema lo suficientemente bueno para explicarles sin tener que bombardearlos con informaciÃģn que no necesitarÃĄn.

Si quieren saber con mÃĄs detalle les recomiendo leer por lo menos uno de estos artículos.

Por ahora les contarÃĐ con un ejemplo uno de los problemas que podemos resolver con un funtor aplicativo.

Imaginen

Imaginen esta situaciÃģn. Tienen un valor y una funciÃģn, y quieren aplicar la funciÃģn a ese valor.

const valor = 1;
const fn = (x) => x + 1;
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

La soluciÃģn es simple.

fn(valor); // => 2
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Todo bien. No necesitamos ningÚn nada mÃĄs. Pero ahora imaginemos que estos valores estÃĄn "atrapados" en una estructura.

const Valor = [1];
const Fn = [(x) => x + 1];
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

En este ejemplo la estructura que usamos es el arreglo. Queremos aplicar la funciÃģn al valor y queremos que el resultado tambiÃĐn sea un arreglo. ÂŋCÃģmo harían eso?

[Fn[0](Valor[0])]; // => [2]
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

ÂŋAsí? No parece apropiado. En un mundo ideal podríamos hacer algo mejor.

Valor.ap(Fn); // => [2]
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Lo que queremos es tratar la aplicaciÃģn de funciones cÃģmo si fuera otra propiedad (o mÃĐtodo) de nuestra estructura.

La mala noticia es que no vivimos en ese mundo. La buena noticia es que implementar esta operaciÃģn nosotros mismos.

const List = {
  ap(Fn, Valor) {
    return Valor.flatMap(x => Fn.map(f => f(x)));
  }
};
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Con esta pequeÃąa funciÃģn podríamos resolver nuestro problema.

const Valor = [1];
const Fn = [(x) => x + 1];

List.ap(Fn, Valor); // => [2]
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

El siguiente paso

Ahora pongamos nuestra atenciÃģn en otra estructura: objetos.

Imaginemos la misma situaciÃģn pero esta vez los elementos que queremos usar estÃĄn atrapados en un objeto de la misma "forma".

const Valor = {email: 'this@example.com'};
const Fn = {email: (input) => input.includes('@')};
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

ÂŋCÃģmo haríamos en este caso? Bueno, tomamos la funciÃģn de una propiedad y la aplicamos al valor correspondiente en el otro objeto. Vamos a implementar esos pasos en una funciÃģn.

const Obj = {
  ap(Fn, Data) {
    const result = {};
    for(let key in Data) {
      result[key] = Fn[key](Data[key]);
    }

    return result;
  }
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Ahora hacemos lo mismo que en el ejemplo anterior.

const Valor = {email: 'this@example.com'};
const Fn = {email: (input) => input.includes('@')};

Obj.ap(Fn, Valor); // => {email: true}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Hagamos una cadena

Bien, podríamos aplicar una validaciÃģn a un campo, Âŋpero es suficiente? Probablemente no. Lo mejor sería devolver un mensaje de error para el usuario. Aparte de eso, tambiÃĐn sería una buena idea poder aplicar varias funciones a la vez.

Lo que quiero hacer es tomar una funciÃģn, un mensaje y poner ambos en un arreglo. Y quiero una lista de esos pares. Algo así.

[
  [long_enough, 'Intenta otra vez'],
  [is_email, 'No es vÃĄlido']
]
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Si la funciÃģn retorna false entonces el mensaje de error es agregado a un arreglo. Sencillo, ÂŋCierto? Vamos a crear una funciÃģn para manejar esta cadena de validaciones.

function validate(validations, input) {
  const error = [];
  for(let [validation, msg] of validations) {
    const is_valid = validation(input);

    if(!is_valid) {
      error.push(msg);
    }
  }

  return error;
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Noten que he dejado el parÃĄmetro input de Último, esto es porque quiero "aplicar" el parÃĄmetro validations sin tener que ejecutar la funciÃģn. Para lograr este efecto usarÃĐ Function.bind.

validate.bind(null, [
  [long_enough, 'Intenta otra vez'],
  [is_email, 'No es un correo vÃĄlido']
]);
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Hay otras formas para lograr la aplicaciÃģn parcial, pero a mi gusta esta.

Lo siguiente serÃĄ implementar las validaciones que queremos ejecutar.

function long_enough(input) {
  return input.length >= 2;
}

function is_email(input) {
  return input.includes("@");
}

function no_numbers(input) {
  return !(/\d/.test(input));
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Ahora podemos poner todo junto en un caso de prueba.

const input = {
  name: '1',
  email: 'a'
};

const validations = {
  name: validate.bind(null, [
    [long_enough, 'Nop. Haz un esfuerzo.'],
    [no_numbers, 'ÂŋNÚmeros? No. Quítalos.']
  ]),
  email: validate.bind(null, [
    [long_enough, 'Intenta otra vez.'],
    [is_email, 'ÂŋA quiÃĐn intentas engaÃąar?']
  ])
};

Obj.ap(validations, input);
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Obj.ap debería devolver esto.

{
  name: [
    "Nop. Haz un esfuerzo.",
    "ÂŋNÚmeros? No. Quítalos."
  ],
  email: [
    "Intenta otra vez.",
    "ÂŋA quiÃĐn intentas engaÃąar?"
  ]
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Si quieren saber si el formulario es vÃĄlido sÃģlo tendrían que revisar si alguna propiedad contiene errores.

function is_valid(form_errors) {
  const is_empty = msg => !msg.length;
  return Object.values(form_errors).every(is_empty);
}

is_valid(Obj.ap(validations, input));
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Luego de evaluar si los datos son vÃĄlidos lo que queda es mostrar los errores al usuario. Esta parte depende mucho del contexto de su programa, no puedo mostrarles un ejemplo lo suficientemente "genÃĐrico" pero sí podemos imaginar otra situaciÃģn mÃĄs específica.

Formulario de registro

Vamos a suponer que tenemos un formulario html cualquiera. Cada campo tiene esta estructura.

<div class="field">
  <label class="label">Nombre Campo:</label>
  <div class="control">
    <input name="nombre-campo" class="input" type="text">
  </div>
  <ul data-errors="nombre-campo"></ul>
</div>
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Cuando el campo es invÃĄlido queremos mostrar la lista de errores en el elemento ul que tiene el atributo data-errors.

ÂŋCÃģmo empezamos? Primero necesitamos agregar una funciÃģn al evento submit de nuestro formulario.

function submit(event) {
  event.preventDefault();
}


document.forms.namedItem("miformulario")
  .addEventListener("submit", submit);
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Nuestro siguiente paso serÃĄ reunir los datos del usuario. Pero en esta escenario no sÃģlo necesitamos el valor de los campos tambiÃĐn necesitamos el nombre del campo. Entonces nuestro objeto va a ser un poco mÃĄs complejo que en el ejemplo anterior.

Vamos a hacer una funciÃģn que de la informaciÃģn que necesitamos del formulario.

function collect_data(form) {
  const result = {};
  const formdata = new FormData(form);

  for (let entry of formdata.entries()) {
    result[entry[0]] = {
      field: entry[0],
      value: entry[1],
    };
  }

  return result;
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Vamos a probarla en la funciÃģn submit.

function submit(event) {
  event.preventDefault();

  const input = collect_data(this);
  console.log(input);
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

En este punto debemos aplicar las validaciones pero la funciÃģn validate que teníamos no serÃĄ suficiente, necesitamos manejar un objeto y no una cadena de texto.

- function validate(validations, input) {
-   const error = [];
+ function validate(validations, field) {
+   const result = {...field};
+   result.errors = [];

    for(let [validation, msg] of validations) {
-     const is_valid = validation(input);
+     result.is_valid = validation(field.value);
-
-     if(!is_valid) {
-       error.push(msg);
+     if(!result.is_valid) {
+       result.errors.push(msg);
      }
    }

-   return error;
+   return result;
  }
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Hemos hecho dos cosas. Primero, sacamos el valor del input de field.value. Segundo, en lugar de un arreglo ahora devolvemos un objeto con la siguiente "forma".

{
  field: String,
  value: String,
  is_valid: Boolean,
  errors: Array
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Hacemos esto porque es muy probable que necesitemos toda la informaciÃģn extra luego de completar el proceso de validaciÃģn.

Justo como antes, vamos a fingir que tenemos que validar nombre y correo de un usuario. Vamos a usar las mismas funciones de antes y nuestro nuevo validate.

function submit(event) {
  event.preventDefault();
  const input = collect_data(this);

  const validations = {
    name: validate.bind(null, [
      [long_enough, 'Nop. Haz un esfuerzo.'],
      [no_numbers, 'ÂŋNÚmeros? No. Quítalos.']
    ]),
    email: validate.bind(null, [
      [long_enough, 'Intenta otra vez.'],
      [is_email, 'ÂŋA quiÃĐn intentas engaÃąar?']
    ])
  };

  const formdata = Obj.ap(validations, input);
  console.log(formdata);
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

ÂŋPero saben quÃĐ? Quiero hacer algo gracioso. Quiero sacar validations de ahí y convertirlo en una funciÃģn usando Obj.ap.bind.

const validate_form = Obj.ap.bind(null, {
  name: validate.bind(null, [
    [long_enough, 'Nop. Haz un esfuerzo.'],
    [no_numbers, 'ÂŋNÚmeros? No. Quítalos.']
  ]),
  email: validate.bind(null, [
    [long_enough, 'Intenta otra vez.'],
    [is_email, 'ÂŋA quiÃĐn intentas engaÃąar?']
  ])
});
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Ahora submit puede ser un poco mÃĄs "declarativo".

function submit(event) {
  event.preventDefault();

  const input = collect_data(this);
  const formdata = validate_form(input);

  console.log(formdata);
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Ahora tenemos que evaluar si el formulario es vÃĄlido. Para esto sÃģlo debemos revisar si todos los campos tienen .is_valid en true. Entonces si el formulario es vÃĄlido lo que queremos hacer es enviar los datos, caso contrario debemos mostrar los errores.

function is_valid(formdata) {
  return Object.values(formdata).every((field) => field.is_valid);
}

function submit(event) {
  event.preventDefault();

  const input = collect_data(this);
  const formdata = validate_form(input);

  if(is_valid(formdata)) {
    send_data(input);
  } else {
    // mostrar errores
  }
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Para el Último paso lo que haremos serÃĄ colocar un li por cada mensaje de error que tenga nuestro input.

function show_errors(input) {
  const el = document.querySelector(`[data-errors=${input.field}]`);
  el.replaceChildren();

  for (let msg of input.errors) {
    const li = document.createElement("li");
    li.textContent = msg;
    el.appendChild(li);
  }
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Esperen... aÚn tenemos que encargarnos de un pequeÃąo detalle que olvidÃĐ. Un funtor aplicativo tambiÃĐn debe tener "mÃĐtodo" map, no tenemos uno pero vamos a arreglar eso.

  const Obj = {
+   map(fn, data) {
+     const result = {};
+     for (let key in data) {
+       result[key] = fn(data[key]);
+     }
+
+     return result;
+   },
    ap(Fn, Data) {
      const result = {};
      for (let key in Data) {
        result[key] = Fn[key](Data[key]);
      }

      return result;
    }
  };
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Ya me siento mejor. Ahora vamos a usar map para mostrar los errores.

function submit(event) {
  event.preventDefault();

  const input = collect_data(this);
  const formdata = validate_form(input);

  if(is_valid(formdata)) {
    send_data(input);
  } else {
    Obj.map(show_errors, formdata);
  }
}
🏆 āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™ ðŸ† āļĒāļ­āļ”āļ™āļīāļĒāļĄ: vonheikemen/como un funtor aplicativo puede ayudarnos a validar formularios - āļ›āļĢāļ°āđ€āļ”āđ‡āļ™āļĢāđ‰āļ­āļ™

Okey ya sÃĐ, map debería usarse para transformar valores. No nos centremos en detalles. Vamos a alegrarnos porque ya todo el trabajo estÃĄ hecho. Aquí les dejo un formulario semi-funcional en codepen para que vean el cÃģdigo en acciÃģn.

ConclusiÃģn

Dimos un pequeÃąo vistazo a lo que pueden hacer los aplicativos con el mÃĐtodo .ap. Sabemos que en javascript no tenemos una implementaciÃģn "nativa" para esto, pero aÚn podemos hacer la nuestra. Y finalmente aplicamos este conocimiento para validar un formulario.


Gracias por su tiempo. Si este artículo les pareciÃģ Útil y quieren apoyar mis esfuerzos para crear mÃĄs contenido pueden dejar una propina en ko-fi.com/vonheikemen.

buy me a coffee

Top comments (0)