Introducción a Node.js, parte 9: Métodos GET y POST con express

Existen dos formas de enviar peticiones http a un servidor, a través del método GET y del método POST. En realidad existen otras, pero no las veremos en esta publicación, ya que me las reservaré para una ocasión más adelante. En fin, la diferencia entre los métodos GET y POST, es que el primero le permite al cliente enviar información al servidor a través de la url, mientras que el segundo se utiliza para enviar información que estará oculta en la cabecera.

Aquí es donde entra en juego el trabajo con formularios, ya que es una de las formas de que el usuario ingrese información, y la envía al servidor. Si bien ya hemos visto en una publicación pasada cómo enviar formularios en Node.js, mediante los métodos GET y POST, Express nos facilita bastante esta tarea.

En primer lugar vamos a hacer lo siguiente: vamos a crear un formulario, donde el usuario podrá ingresar un asunto y un mensaje, y lo enviará a través de un formulario mediante POST. Luego se recargará esa página, que nos mostrará todos los mensajes que han ido guardándose en una variable, que tendrá una suerte de base de datos.

Comencemos por crear la vista para esto. Vamos a ir a nuestra carpeta views, y dentro crearemos una sub carpeta llamada mensajes, y aquí dentro un archivo llamado enviar_mensaje.jade. Este tendrá el siguiente código:

extends ../layout
block content
  h1 Enviar mensaje
  form(method="post", action="/enviar_mensaje")
    label Asunto
    br
    input(type="text", name="asunto")
    br
    label Mensaje
    br
    textarea(cols="40", rows="10", name="mensaje")
    br
    input(type="submit", value="Enviar mensaje")
  ul
    -for (i in lista)
      li #{lista[i].asunto}

Como se ve en el ejemplo, tenemos un formulario con dos campos de ingreso, un input text para ingresar el asunto, y un textarea para el mensaje. Y Obviamente el botón para enviar el formulario.

Además tendremos un bucle de repetición para cargar la lista de todos los mensajes enviados.

Ahora nos toca crear la acción, así que vamos a la carpeta routes, y ahí dentro vamos a crear un nuevo módulo al que llamaremos mensajes.js. Este archivo tendrá el siguiente código:

var lista = new Array();
function enviar_mensaje(req, res){
   res.render('mensajes/enviar_mensaje', {
      lista: lista
   });
}
exports.get_enviar_mensaje = function(req, res){
   enviar_mensaje(req, res);
}
exports.post_enviar_mensaje = function(req, res){
   var asunto = req.body.asunto;
   var mensaje = req.body.mensaje;
   lista.push({
      asunto: asunto,
      mensaje: mensaje
   })
   enviar_mensaje(req, res);
}

En primer lugar creamos una variable que será la que guarde todos los mensajes enviados:

var lista = new Array();

Luego tendremos una función que nos cargará una vista con un formulario y le pasará la lista de todos los mensajes enviados:

function enviar_mensaje(req, res){
   res.render('mensajes/enviar_mensaje', {
      lista: lista
   });
}

Y finalmente tendremos dos funciones. La que se accederá por GET:

exports.get_enviar_mensaje = function(req, res){
   enviar_mensaje(req, res);
}

Y la que se accederá por POST:

exports.post_enviar_mensaje = function(req, res){
   var asunto = req.body.asunto;
   var mensaje = req.body.mensaje;
   lista.push({
      asunto: asunto,
      mensaje: mensaje
   })
   enviar_mensaje(req, res);
}

Ambas acciones hacen lo mismo, llaman a la función enviar_mensaje(), con la diferencia que la segunda primero recupera los valores que se enviaron del formulario, para finalmente guardarlos en la variable lista.

Acá podemos ver lo fácil que es recibir variables de tipo POST con Express:

var asunto = req.body.asunto;
var mensaje = req.body.mensaje;

La primera será para guardar una variable de tipo POST llamada asunto, y la segunda mensaje.

Ahora, para que todo esto esté disponible vamos a ir a nuestro archivo app.js, y vamos a buscar el apartado del código donde se cargar los módulos, por ejemplo:

var user = require('./routes/user');

Ahí, debajo vamos a agregar el módulo que acabamos de crear:

var mensajes = require('./routes/mensajes');

Y finalmente vamos a donde se encuentran las acciones, y copiamos el siguiente código:

app.get('/enviar_mensaje', mensajes.get_enviar_mensaje);
app.post('/enviar_mensaje', mensajes.post_enviar_mensaje);

Como se ve en el ejemplo, ambas tienen la misma url, pero la diferencia es que la que se accederá por GET, llamará a la función get_enviar_mensaje(), mientras que la se accede por POST a post_enviar_mensaje().

Si bien, hasta ahora venimos creando todo el código de las acciones dentro de app.js, en esta ocasión decidí separarlo en módulos. De esta manera sería bueno tener todo ordenado en distintos módulos, para que ese archivo, app.js, no termine siendo una bolsa de gatos, con cien mil millones de líneas.

Y ahora vamos a agregar la posibilidad de leer el mensaje completo, al hacer clic en cada item de la lista de los mensajes. Para ello, necesitamos una acción que tomará desde la url un identificador, podría ser un id, pero como nosotros estamos usando un array, vamos a usar el sub índice de cada posición.

Podríamos hacer esto mediante las tradicionales variables GET, con el signo de interrogación, el nombre de la variable y el valor:

?nombre=valor

Sin embargo, Express nos da la posibilidad de crear url con datos dinámicos, pero más limpias que las que acabamos de nombrar.

Primero vamos a modificar la vista enviar_mensaje.jade, en views -> mensajes -> enviar_mensaje.jade. Reemplazaremos las líneas:

ul
  -for (i in lista)
    li #{lista[i].asunto}

Por:

ul
  -for (i in lista)
    li
      a(href="/mensaje/#{i}") #{lista[i].asunto}

Seguimos editando la vista que nos mostrará el mensaje completo. Así que vamos a views -> mensajes y creamos un archivo con el nombre mensaje.jade, con el siguiente código:

extends ../layout
block content
  h1 Mensaje
  -if(mensaje)
    h2= mensaje.asunto
    div= mensaje.mensaje
  -else
    p Mensaje no encontrado
  p
    a(href="/enviar_mensaje") Volver atrás

Vamos a agregar la acción que recupera el mensaje, así que vamos a nuestro modulo mensajes, en routes -> mensajes.js, y agregamos una nueva función:

exports.get_mensaje = function(req, res){
   var indice = req.params.indice;
   var mensaje = (lista[indice] != undefined) ? lista[indice] : null;
   res.render('mensajes/mensaje', {
      mensaje: mensaje
   });
}

Como se ve en el ejemplo, recuperamos la variable que ha venido en la url, la variable indice:

var indice = req.params.indice;

Luego verificamos que exista un mensaje con ese sub índice:

var mensaje = (lista[indice] != undefined) ? lista[indice] : null;

Y se lo pasamos a la vista:

res.render('mensajes/mensaje', {
   mensaje: mensaje
});

Ahora, volvemos a nuestro archivo principal app.js, para agregar esta nueva acción:

app.get('/mensaje/:indice', mensajes.get_mensaje);

Notar que cuando pasamos una variable por la url, debemos usar los dos puntos adelante para indicar que será un valor dinámico.

Yo podemos compilar el archivo app.js y probar todo.

Saludos!

Descargar ejemplo

Anterior: Introducción a Node.js, parte 8: Express y Jade

Siguiente: Introducción a Node.js, parte 10: Archivos públicos con express

Redes sociables

    7 Replies to “Introducción a Node.js, parte 9: Métodos GET y POST con express”

    1. Hola Ferchu,

      ¿Y si en lugar de un chat se quisiera montar un sistema de publicación tipo twiter, muro de facebook, o más simple que eso, donde el cliente solo se conectara y recibiera notificaciones?

      No me queda claro como sería la lógica para estos casos. Supongo que el cliente se conecta como en el chat y el servidor realiza consultas continuamente a una base de datos o a un servicio web y le notifica a los clientes conectados si hay nueva información.

      Un saludo

      1. Antonio, el objetivo de esta publicación no es la de crear un chat, ni guardar comentarios en una base de datos, sino saber cómo se envían formularios con Express.

        Francamente entiendo lo que decís, pero más adelante vemos base de datos y la creación de un chat.

        Saludos!

        1. Fallo mío, tienes toda la razón. Quería poner el comentario en el ejemplo del chat y me he equivocado de pestaña del navegador.

          Puesto que estoy muy interesado en el tema expuesto en el anterior comentario, y creo que puede ser de interés para más gente, copio y pego donde toca 😉

          Saludos

    2. Me sale el siguiente error:

      Cannot read property ‘asunto’ of undefined

      TypeError: Cannot read property ‘asunto’ of undefined
      at Object.exports.post_enviar_mensaje [as handle] (C:\Program Files\nodejs\proyecto\routes\mensajes.js:11:25)

    Comments are closed.