Desde: 29-Mar-2023
Hasta 29-Ago-2023
Modo

Agregar datos a la base de datos (6ta parte).

Omar Giancarlo

Descripción Corta:

Aprende cómo agregar datos a la base de datos de manera efectiva utilizando la opción AUTO_INCREMENT para generar IDs automáticamente.

Anterior Siguiente

En esta sección vamos a ver cómo agregar datos a la base de datos y colocarlo dentro de la tabla en la base de datos. Para poder hacer esto recordemos que ya tenemos una tabla creada que se llama employees. Esta tabla employees recibe un nombre, un salario, el ID que no es necesario que se lo generemos porque esto se va a generar por sí solo, ya que utilizamos la opción de AUTO_INCREMENT al momento de crear la tabla.

Si te perdiste la parte 5 de esta serie puedes ir aquí.

Para poder entender cómo funciona de momento vamos a crear una inserción utilizando la sintaxis de SQL.

INSERT INTO employee VALUE
(1, 'JOE', 1000),
(2, 'HENRY', 2000),
(3, 'SAM', 2500),
(4, 'MAX', 1500);

En phpMyAdmin vamos a buscar la base de datos y la tabla que creamos. En la pestaña SQL pegamos ese código, seguido presionamos el botón continuar.

Presionamos en la tabla en la que estamos trabajando, y vamos a poder ver los valores insertados.

Ahora vamos a ir al archivo employees.controller.js y en la función createEmployees() vamos a cambiar el texto que dice "agregando empleado" por esa consulta.

const createEmployees = (req, res) => res.send( 'agregando empleados' )

Primero vamos a empezar quitando res.send('agregando empleados') y le agregamos unas { } y quedaría de la siguiente manera:

const createEmployees = (req, res) => {
     
    }

Conectando a la base de datos

Para poder agregar datos a la base de datos, vamos a necesitar el objeto pool junto con el método query() para poder realizar la consulta a la base de datos:

const pool = require('../db.js')

const util = require('util')

const query = util.promisify(pool.query).bind(pool)

A partir del método query() directamente podemos hacer la consulta como explicamos anteriormente.

query( 'INSERT INTO employees')

Utilizando sintaxis SQL

Para pasarle los datos en este caso, vamos a insertarlos en grupo. Es algo similar a como hicimos cuando insertamos los valores directamente en la tabla en phpMyAdmin. Utilizando sintaxis de SQL vamos a pasar los valores que queremos insertar, Por ejemplo, si queremos pasarle nombre y salario tengo que utilizar VALUES (?, ?) donde los valores los ponemos entre paréntesis y un signo de interrogación que va a referirse al primer valor y otro signo de interrogación que va a referirse al segundo valor, estos valores los vamos a tomar de un arreglo [ ] ubicado como segundo argumento dentro de la función query().

query('INSERT INTO employees (name, salary) VALUES (?, ?)', [])

Ahora la función createEmployees tiene que recibir los datos que una función cliente le va a enviar. Para poder hacer esto primero tengo que ver de alguna forma estos datos. Para esto vamos a ir a Thunder client y hacemos una petición POST a la ruta /employees.

De momento no se obtiene nada, así que vamos a responder un texto que diga "post-success".

const createEmployees = async (req, res) => {
    try {
      //query('INSERT INTO employee (name, salary) VALUES (?, ?)', [])
        res.send('post success')
      } catch (error) {
        console.error(error)
        res.status(500).send('Error al obtener la información')
      }
}

Ahora colocamos:

console.log(req.body)

Ahora vamos a ver por consola desde (req) la propiedad que se llama body, para poder ver los datos que el cliente envía al momento que hace esta petición.

Guardamos y otra vez enviamos /employees a través de POST, para saber qué nos va a mostrar, en este caso dice Undefined. Esto es porque de momento no me está pasando ningún dato. Pero sí vamos a la pestaña donde dice body dentro de Thunder client y colocamos algún JSON válido.

{
  "name": "Omar",
  "salary": 1000
}

Y presionamos enviar, vamos a ver qué nos responde 'post success'. Si vamos a la terminal vamos a ver que sigue diciendo undefined. Me sigue diciendo undefined porque a pesar de que le estamos mandando un JSON válido, el backend no lo puede entender todavía. 

Haciendo que Express reconozca JSON

Entonces para hacer que entienda vamos a ir a index.js, este archivo tiene el objeto app que tiene una función especial que permite interpretar estos datos. Entonces, en index.js antes de que lleguen a las rutas, es muy importante decirle que desde Express vamos a utilizar el método llamado json()

Este método json() es como decir, primero voy a recibir los datos y después los voy a convertir en un JSON o en un objeto de JavaScript.

Luego se los voy a pasar a las rutas, de esta forma todas las rutas que ya fueron procesadas van a poder interpretar el valor que la función json() le haya pasado.

app.use(express.json())

Guardamos y nuevamente enviamos la ruta /employees en POST, vamos a ver que en consola nos muestra el objeto JSON que habíamos creado en el body de Thunder client.

Extraer los valores enviados desde la extensión Thunder client

Para este ejemplo sencillo vamos a extraer los valores de request.body que van a ser name y salary.

const { name, salary } = req.body

Como vemos estamos usando desestructuración para obtener name y salary, ahora vamos a volver a la función createEmployees y vamos a, des comentar la línea de código que correspondería a la consulta a la base de datos. Vemos que el primer valor es el nombre, es decir, el nombre y el otro dato es el salario.

Es muy importante que mantengamos el orden. El primer valor hace referencia al primer signo de interrogación y segundo valor corresponde al segundo signo de interrogación respectivamente VALUES (?, ?)

Esto es una consulta asíncrona, así que tenemos que agregar el async await.

const createEmployees = async (req, res) => {
    try {
      const { name, salary } = req.body
      await query('INSERT INTO employee (name, salary) VALUES (?, ?)', [name, salary])
        res.send('post success')
      } catch (error) {
        console.error(error)
        res.status(500).send('Error al obtener la información')
      }
   }

Para tener más clara esta idea, cuando hacemos cualquier tipo de operación con la base de datos, siempre es una consulta asíncrona. 

Respuesta que se obtiene de la base de datos

Entendido esto, al agregar datos a la base de datos, esta consulta devuelva una respuesta, solamente se va a necesitar las filas (rows) que son las filas insertadas. A partir de aquí voy a devolver, rows es decir, enviar esas filas como un objeto JSON.

const createEmployees = async (req, res) => {
    try {
        const { name, salary } = req.body
        const [rows] = await query('INSERT INTO employee (name, salary) VALUES (?, ?)', [name, salary])
        res.send({rows})
      } catch (error) {
        console.error(error)
        res.status(500).send('Error al obtener la información')
      }
}

Si guardamos, vamos a la consola y vemos que todo funciona normalmente. Sin embargo, lo que vamos a hacer es ir a la extensión Thunder client y nuevamente hacer la misma petición POST.

En este caso envía un error y este error está relacionado con lo que me está devolviendo el método query(), este error es porque estaba devolviendo un objeto que no es iterable, entonces lo que hice fue modificar la forma cómo iba a almacenar lo que me devuelve la consulta a la base de datos de esta manera:

const rows = await query('INSERT INTO employee (name, salary) VALUES (?, ?)', [name, salary])

Guardo y vuelvo a ejecutar la consulta, obteniendo este objeto que se muestra a continuación.

 {
  "rows": {
    "fieldCount": 0,
    "affectedRows": 1,
    "insertId": 15,
    "serverStatus": 2,
    "warningCount": 0,
    "message": "",
    "protocol41": true,
    "changedRows": 0
  }
}

Este objeto es lo que la base de datos ha respondido al servidor, y el servidor a su vez está respondiendo al cliente, que dé toda esta respuesta, lo único que nos importa es la propiedad insertId.

Este es el ID del nuevo registro. Es decir, que si nosotros vamos y consultamos directamente la base de datos en phpMyAdmin veremos el nuevo usuario con su ID, nombre y salario.

Obteniendo todos los datos juntos id, name y salary dentro del objeto

Ahora quiero que me devuelva los mismos datos unidos al ID que se ha generado y para esto, tendríamos que hacer lo siguiente:

const createEmployees = async (req, res) => {
    try {
        const { name, salary } = req.body
        const rows = await query('INSERT INTO employee (name, salary) VALUES (?, ?)', [name, salary])
        res.send({
            id: rows.insertId,
            name,
            salary
        })
      } catch (error) {
        console.error(error)
        res.status(500).send('Error al obtener la información')
      }
}

Esto me va a devolver los mismos datos, pero con el nuevo ID, guardamos y vamos a probarlo. 

Nuevamente, vamos a ir a la extensión Thunder client, hacemos la petición, POST, pero en este caso vamos a cambiar el nombre del usuario y le vamos a cambiar el salario, como podemos ver, me respondió el nuevo usuario, con su correspondiente nuevo id.

{
  "id": 17,
  "name": "Emilio",
  "salary": 7000
}

Con esto ya estamos insertando datos dentro de nuestra API, de forma básica. También se podría hacer antes de recibir los datos, validar, pasarlo por funciones condicionales o validar que los datos enviados sean una cadena, etc. Pero para este ejemplo sencillo hasta acá está bien.

Ir a la parte 7

Anterior Siguiente