"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > [Asado: Día - Mi carpeta `utils`

[Asado: Día - Mi carpeta `utils`

Publicado el 2024-08-27
Navegar:226

[Roast: Day  - My `utils` Folder

La mayor parte del trabajo de hoy ha sido una continuación del trabajo de ayer, simplemente implementando lógica de negocios en las rutas de mi aplicación. Entonces, pensé en tomarme un descanso de escribir sobre eso para hablar sobre tres funciones que he creado para hacer cosas muy específicas en mi aplicación.

¿Qué es una carpeta de utilidades?

Este es el directorio donde colocas todas tus pequeñas funciones a las que les cuesta encontrar un hogar, pero tu aplicación no podría vivir sin ellas.

Una carpeta de utilidades es el vertedero de los héroes anónimos de muchas aplicaciones.

Cuando tengas que realizar una transformación de tus datos que requerirá más de unas pocas líneas de código y que tendrás que reutilizar, es una buena idea colocarlos en su propio archivo que puedas exportar al resto de su solicitud.

¿Por qué no simplemente copiamos y pegamos? Bueno, esto violaría dos principios de programación, DRY y separación de preocupaciones.

No te repitas

Repetirse no solo es monótono, sino que también es difícil cambiar si lo ha hecho lo suficiente a lo largo de su solicitud. Imagine un algoritmo que calcule el porcentaje de probabilidad de que llueva hoy.

No sé cómo la gente hace eso, así que no puedo mostrarte un ejemplo. Pero, si copia todo esto en su código en los diferentes lugares que necesitan tener acceso a este cálculo, se enojará mucho cuando el Comité Meteorológico Científico Muy Inteligente regrese con un algoritmo nuevo y más preciso. &&&]

Tome partes reutilizadas de su código y encuentre formas de empaquetarlas para usarlas en varios lugares, sin dejar de actualizarlas en un solo lugar.

¡Todas las funciones de mi carpeta de utilidades se utilizan en muchos lugares de mi aplicación!

Separación de preocupaciones

Como programadores, tampoco queremos crear funciones que hagan MUCHAS cosas diferentes. Preferiríamos tener MUCHAS funciones que hicieran una sola cosa. ¿Por qué? Bueno, ¡hace que estas funciones sean más reutilizables!

¿Qué tiene esto que ver con una carpeta de utilidades? Bueno, las funciones que estoy a punto de repasar realmente no tienen un lugar dentro de funciones como getRoastsById porque ¡eso no es lo que hacen! Cuando necesitemos hacer algo más, debemos crear una función para ello. Pero, cuando no tenemos un lugar lógico para esa función, debido a que es una "ayuda", ¡la guardamos en nuestro directorio de utilidades!

Mi carpeta de utilidades

Tengo tres utilidades personalizadas hasta ahora:

    insertarDeclaración
  • actualizaciónDeclaración
  • objetoKeysToCamel
Con suerte, por sus nombres queda claro lo que hacen, pero permítanme compartir brevemente el problema que resuelven y cómo funcionan.

insertar declaración

Problema: En muchos de los diferentes servicios de mi aplicación, se me pedirá que realice una consulta INSERT a mi base de datos. Estas declaraciones requieren que usted enumere explícitamente 1) los nombres de las columnas y 2) los valores. No debería tener que escribirlos en cada ruta, así que creé una función para hacerlo por mí.

Entrada: La función toma dos parámetros, table una cadena que coincide con el nombre de una tabla en la base de datos y obj, un objeto Javascript que representa el modelo que el usuario desea agregar a la base de datos.

Salida: Un objeto con 1) una cadena INSERT con formato de propiedad con valores de marcador de posición y 2) una matriz de los valores que se utilizarán en una consulta parametrizada.

const { SnakeCase } = require('cambiar-caso-commonjs'); función insertarStatement(tabla, obj) { claves constantes = Object.keys(obj); valores constantes = Objeto.valores(obj); let declaración = `INSERT INTO ${table} (`; // Agrega claves de Snake_case a la declaración const keyString = llaves.map((clave, i) => SnakeCase(clave)).join(', '); declaración = `${keyString}) VALORES (`; //Añadir marcadores de posición para los valores marcadores de posición constantes = llaves.map((_, i) => `$${i 1}`).join(', '); declaración = `${placeholders}) REGRESANDO *;`; // Devuelve la cadena de consulta y la matriz de valores devolver { texto: declaración, valores: valores }; } módulo.exportaciones = insertStatement;
const { snakeCase } = require('change-case-commonjs');

function insertStatement(table, obj) {
  const keys = Object.keys(obj);
  const values = Object.values(obj);

  let statement = `INSERT INTO ${table} (`;

  // Add snake_case keys to the statement
  const keyString = keys.map((key, i) => snakeCase(key)).join(', ');
  statement  = `${keyString}) VALUES (`;

  // Add placeholders for the values
  const placeholders = keys.map((_, i) => `$${i   1}`).join(', ');
  statement  = `${placeholders}) RETURNING *;`;

  // Return the query string and the values array
  return {
    text: statement,
    values: values
  };
}

module.exports = insertStatement;
actualizarDeclaración

Problema: Similar a la instrucción INSERT, la instrucción UPDATE requiere que indiques explícitamente tanto los nombres de las columnas como los valores en tu consulta. Esta sintaxis es diferente de una declaración INSERT. A través de la lógica condicional, podría crear una función de base de datosQueryGenerator, pero esto también parece violar la separación de preocupaciones. ¿Una función como esa decidiría qué tipo de consulta desea o generaría una sintaxis basada en eso?

Entrada: La función toma tres parámetros. obj, un objeto JavaScript que representa el registro actualizado. table , una cadena que debe coincidir con una tabla de la base de datos. id , un número entero que coincide con el registro que se actualizará con la nueva información.

Salida: Un objeto con 1) una cadena UPDATE formateada por propiedad con valores de marcador de posición y 2) una matriz de los valores que se utilizarán en una consulta parametrizada.

const { SnakeCase } = require('cambiar-caso-commonjs'); función actualizarDeclaración(obj, tabla, id) { claves constantes = Object.keys(obj); valores constantes = Objeto.valores(obj); let declaración = `ACTUALIZAR ${tabla} SET `; llaves.forEach((clave, índice) => { declaración = `${snakeCase(clave)} = $${índice 1}, `; }); // Elimina la última coma y el espacio. declaración = declaración.slice(0, -2); // Determinar la columna de ID correcta según la tabla const idColumn = tabla === 'usuarios'? 'nombre de usuario': tabla === 'asados'? 'asado_id': ''; // Finaliza la declaración con la cláusula WHERE declaración = ` DONDE ${idColumn} = $${keys.length 1} REGRESANDO *;`; devolver { texto: declaración, valores: [...valores, id] }; } módulo.exportaciones = declaración de actualización
const { snakeCase } = require('change-case-commonjs');

function insertStatement(table, obj) {
  const keys = Object.keys(obj);
  const values = Object.values(obj);

  let statement = `INSERT INTO ${table} (`;

  // Add snake_case keys to the statement
  const keyString = keys.map((key, i) => snakeCase(key)).join(', ');
  statement  = `${keyString}) VALUES (`;

  // Add placeholders for the values
  const placeholders = keys.map((_, i) => `$${i   1}`).join(', ');
  statement  = `${placeholders}) RETURNING *;`;

  // Return the query string and the values array
  return {
    text: statement,
    values: values
  };
}

module.exports = insertStatement;
objetoKeysToCamel

Problema: El estilo de mi base de datos es diferente al estilo de mi JavaScript. Sin embargo, no estoy dispuesto a ceder en ninguna de las áreas. En mis archivos JS, mi convención de nomenclatura usa camelCase, mientras que en mi base de datos usa Snake_case. Todos los nombres de propiedad de los objetos devueltos son iguales, pero tienen un formato diferente. Para mantener este estándar de casos, tendría que acceder a las propiedades en mi JS usando Snake_case, pero esto no me gusta.

Entrada: La función toma solo un parámetro, un objeto obj JavaScript cuyas claves deberían transformarse al formato camelCase.

Salida: El mismo objeto, con claves formateadas en camelCase.

const { camelCase } = require('cambiar-caso-commonjs'); función objetoKeysToCamel(obj) { // Extrae las claves y los valores claves constantes = Object.keys(obj); valores constantes = Objeto.valores(obj); dejar camello = {} // Cambia el formato de cada clave, asignándole el valor adecuado claves.forEach((clave, i) => { const camelKey = camelCase(clave); camello[llavecamello] = valores[i] }) // Devuelve el nuevo objeto camello de regreso; } módulo.exportaciones = objectKeysToCamel;
const { camelCase } = require('change-case-commonjs');

function objectKeysToCamel(obj) {
  // Extract the keys and values
  const keys = Object.keys(obj);
  const values = Object.values(obj);
  let camel = {}

  // Change the formatting of each key, assigning it the proper value
  keys.forEach((key, i) => {
    const camelKey = camelCase(key);
    camel[camelKey] = values[i]
  })

  // Return the new object
  return camel;
}

module.exports = objectKeysToCamel;

Mira el proyecto

Si desea mantenerse al día con los cambios, bifurcar y ejecutar localmente, o incluso sugerir cambios de código, ¡aquí tiene un enlace al repositorio de GitHub!

https://github.com/nmiller15/roast

¡La aplicación frontend está actualmente implementada en Netlify! Si desea probar algunas funciones y verlas en acción, véalas en un dispositivo móvil a continuación.

https://knowyourhomeroast.netlify.app

Nota: Esta implementación no tiene una API de backend, por lo que las cuentas y los roasts en realidad no se guardan entre sesiones.

Declaración de liberación Este artículo se reproduce en: https://dev.to/nmiller15/roast-day-16-my-utils-folder-33dm?1 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3