Header Ads Widget

Ticker

6/recent/ticker-posts

Creación de una aplicación CRUD simple con Node, Express y MongoDB

 Finalmente entendí cómo trabajar con Node, Express y MongoDB. Quiero escribir un tutorial completo para que no tengas que pasar por el mismo dolor de cabeza que yo pasé.

CRUD, Express y MongoDB

CRUD, Express y MongoDB son grandes palabras para una persona que nunca ha tocado ninguna programación del lado del servidor en su vida. Presentemos rápidamente cuáles son antes de sumergirnos en el tutorial.

Expreso es un marco para la creación de aplicaciones web en la parte superior de Node.js . Simplifica el proceso de creación del servidor que ya está disponible en Node. En caso de que se lo esté preguntando, Node le permite usar JavaScript como su idioma del lado del servidor.

MongoDB es una base de datos . Este es el lugar donde almacena información para sus sitios web (o aplicaciones).

CRUD es un acrónimo de Create, Read, Update y Delete . Se trata de un conjunto de operaciones que obtenemos servidores para ejecutar (POST,GET,PUTyDELETElas solicitudes respectivamente). Esto es lo que hace cada operación:

  • Crear (POST) : hacer algo
  • Leer (OBTENER) - Obtener algo
  • Actualizar (PUT) : cambiar algo
  • Eliminar (BORRAR) : eliminar algo

POSTGETPUT, Y DELETElas solicitudes construyamos API Rest .

Si juntamos CRUD, Express y MongoDB en un solo diagrama, este es el aspecto que tendría:

¿CRUD, Express y MongoDB tienen más sentido para usted ahora?

Excelente. Vamonos.

Construiremos juntos una aplicación sencilla

Creemos una aplicación simple que te permita rastrear una lista de citas de personajes de Star Wars. Así es como se ve:

Agrega CSS para que la aplicación se vea mejor.

Gratis gratis para ver la demostración antes de continuar con este tutorial.

¡Este artículo es LARGO! Recuerde tomar el código fuente dejando su nombre y dirección de correo electrónico en este formulario . También te enviaré este artículo en PDF para que puedas leerlo en tu tiempo libre.

Por cierto, no me voy a centrar en los estilos, ya que nos centramos en aprender Crud, Express y MongoDB en este tutorial.

Prerrequisitos

Necesitará dos cosas para comenzar con este tutorial:

  1. No tiene miedo de escribir comandos en una línea de comandos. Si tiene miedo, utilice este artículo para superarlo .
  2. Necesitas tener Node instalado.

Para verificar si tiene Node instalado, abra su Línea de Comando y ejecute el siguiente código:

$ node -v
Versión de nodo

Debería obtener un número de versión si tiene Node instalado. Si no lo hace, puede instalar Node descargando el instalador del sitio web de Node o descargándolo a través de administradores de paquetes como Homebrew (Mac) y Chocolatey (Windows).

Empezando

Comience creando una carpeta para este proyecto. No dudes en llamarlo como quieras. Una vez que haya creado la carpeta, navegue hacia ella con la Terminal y ejecute npm init.

npm initcrea un package.jsonarchivo que le ayuda a administrar las dependencias (que instalaremos a medida que avancemos en el tutorial).

$ npm init
npm init.

Simplemente presione enter a través de todo lo que aparece. Hablaré sobre los que necesita saber a medida que avanzamos.

Ejecutando Node por primera vez en tu vida

La forma más sencilla de utilizar el nodo es ejecutar el nodecomando y especificar una ruta a un archivo. Creemos un archivo llamado server.jspara ejecutar el nodo.

touch server.js

A continuación, ponga esta console.logdeclaración en server.jsEsto nos permite saber si Node se está ejecutando correctamente.

// server.js
console.log('May Node be with you')

Ahora, ejecute node server.jssu línea de comando y debería ver esto:

 
Nodo registrado puede estar contigo.

Excelente. El nodo funciona. El siguiente paso es aprender a usar Express.

Usando Express

Primero, tenemos que instalar Express. Podemos hacer esto ejecutando el npm installcomando. npmestá instalado con Node, por lo que usa comandos como npm initnpm install).

Ejecute el npm install express --savecomando en su línea de comando.

La --savebandera guarda expresscomo dependencyen package.jsonEs importante conocer estas dependencias porque npmpuede recuperar dependencias con otro npm installcomando cuando lo necesite más adelante.

npm install express --save
 
Expreso guardado como dependencia

A continuación, usamos express in server.jsrequiriéndolo.

const express = require('express');
const app = express();

Necesitamos crear un servidor al que los navegadores puedan conectarse. Hacemos esto usando el listenmétodo Express .

app.listen(3000, function() {
console.log('listening on 3000')
})

Ahora, ejecute node server.jsy navegue hasta localhost:3000en su navegador. Debería ver un mensaje que dice cannot get /.

 
No puedo conseguirlo /.

Buena seńal. Significa que ahora podemos comunicarnos con nuestro servidor express a través del navegador . Aquí es donde comenzamos las operaciones CRUD.

CRUD - LEER

Los navegadores realizan la operación READ cuando visita un sitio web. Bajo el capó, envían una solicitud GET al servidor para realizar esta operación READ.

Verá cannot get /porque nuestro servidor no envió nada al navegador.

En Express, manejamos una solicitud GET con el getmétodo:

app.get(endpoint, callback)

endpointes el punto final solicitado. Es el valor que viene después de su nombre de dominio. Aquí hay unos ejemplos:

  • Cuando visitas localhost:3000, en realidad estás visitando localhost:3000/En este caso, los navegadores solicitados /.
  • Estás leyendo este artículo en https://zellwk.com/blog/crud-express-mongodb/El nombre de dominio es zellwk.comEl punto final solicitado es todo lo que viene después zellwk.com(que es /blog/crud-express-mongodb).

callbackle dice al servidor qué hacer cuando el punto final solicitado coincide con el punto final indicado. Toma dos argumentos: un requestobjeto y un responseobjeto.

// We normally abbreviate `request` to `req` and `response` to `res`.
app.get('/', function (req, res) {
// do something here
})

Por ahora, volvamos a escribir Hello Worlden el navegador. Lo hacemos usando un sendmétodo que viene con el responseobjeto:

app.get('/', function(req, res) {
res.send('Hello World')
})

Comenzaré a escribir en código ES6 y también le mostraré cómo convertir a ES6 en el camino. En primer lugar, lo estoy reemplazando function()con una función de flecha ES6 . El siguiente código es el mismo que el anterior:

app.get('/', (req, res) => {
res.send('Hello World')
})

Ahora, reinicie su servidor haciendo lo siguiente:

  1. Detenga el servidor actual presionando CTRL + Cen la línea de comando.
  2. Corre de node server.jsnuevo.

Luego, navegue hasta localhost:3000en su navegador. Debería poder ver una cadena que dice "Hola mundo".

 

Excelente.

A continuación, cambiemos server.jspara mostrar una index.htmlpágina al navegador. Para hacer esto, usamos el sendFilemétodo proporcionado por el resobjeto.

app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html')
// Note: __dirname is the current directory you're in. Try logging it and see what you get!
// Mine was '/Users/zellwk/Projects/demo-repos/crud-express-mongo' for this app.
})

En el sendFilemétodo anterior, le dijimos a Express que sirviera un index.htmlarchivo que se puede encontrar en la raíz de la carpeta de su proyecto. Aún no tenemos ese archivo. Hagámoslo ahora.

touch index.html

Pongamos algo de texto en nuestro index.htmlarchivo también:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MY APP</title>
</head>
<body>
<h1> May Node and Express be with you. </h1>
</body>
</html>

Reinicie su servidor y actualice su navegador. Debería poder ver su archivo HTML ahora.

 
El archivo HTML.

Así es como Express maneja una solicitud GET ( operación READ ) en pocas palabras.

En este punto, probablemente se haya dado cuenta de que necesita reiniciar su servidor cada vez que realice un cambio en server.jsEste proceso es increíblemente tedioso, así que tomemos un desvío rápido y simplifíquelo utilizando una herramienta llamada nodemon .

Ingrese Nodemon

Nodemon reinicia el servidor automáticamente cuando guarda un archivo que usa server.jsPodemos instalar Nodemon con el siguiente comando:

$ npm install nodemon --save-dev

Usamos una --save-devbandera aquí porque solo usamos Nodemon cuando estamos desarrollando cosas. No usaremos Nodemon en un servidor real. --save-devaquí agrega Nodeman como devDependencyen el package.jsonarchivo.

Nodemon guardado como una dependencia de desarrollo.

Nodemod se comporta como Node. Entonces puedes correr nodemon server.jsy esperarías ver lo mismo. Desafortunadamente, esto solo funciona si ha instalado nodemon globalmente con la -gbandera (y no hicimos esto).

Tenemos otras formas de ejecutar Nodemon. Por ejemplo, puede ejecutar Nodemon directamente desde la node_modulescarpeta. Esto es muy desagradable, pero funciona:

./node_modules/.bin/nodemon server.js

Podemos simplificar las cosas agregando una  scriptclave en el package.jsonarchivo. Esto nos permite correr nodemon server.jssin el ./node_modules...preámbulo.

{
// ...
"scripts": {
"dev": "nodemon server.js"
}
// ...
}

Ahora, puedes correr npm run devpara disparar nodemon server.js.

Utiliza npm run dev para ejecutar nodemon server.js

Volviendo al tema principal. A continuación, cubriremos la operación CREAR .

CRUD - CREAR

Los navegadores solo pueden realizar una operación CREATE si envían una solicitud POST al servidor. Esta POSTsolicitud se puede activar mediante JavaScript o mediante un <form>elemento.

Averigüemos cómo usar un <form>elemento para crear nuevas entradas para esta aplicación de cotización de Star Wars por ahora. Examinaremos cómo enviar solicitudes a través de JavaScript más adelante.

Para enviar una solicitud POST a través de a <form>, debe agregar el <form>elemento a su index.htmlarchivo.

Necesita tres cosas en este elemento de formulario:

  1. Un actionatributo
  2. Un methodatributo
  3. nameatributos en cada <input>elemento dentro del formulario
<form action="/quotes" method="POST">
<input type="text" placeholder="name" name="name">
<input type="text" placeholder="quote" name="quote">
<button type="submit">Submit</button>
</form>

Le methoddice a los navegadores qué tipo de solicitud enviar. En este caso, usamos POSTporque estamos enviando una POSTsolicitud.

El actionatributo le dice al navegador dónde enviar la POSTsolicitud. En este caso, enviamos la POSTsolicitud a /quotes.

Podemos manejar esta POSTsolicitud con un postmétodo en server.jsLa pathruta debe ser el valor que colocó en el actionatributo.

app.post('/quotes', (req, res) => {
console.log('Hellooooooooooooooooo!')
})

Reinicie su servidor (es de esperar que haya configurado Nodemon para que se reinicie automáticamente) y actualice su navegador. Luego, ingrese algo en el <form>elemento y envíe el formulario. A continuación, mire su línea de comandos. Debería ver Hellooooooooooooooooo!en su línea de comando.

 
Registra helloooo en la línea de comando.

Genial, sabemos que Express está manejando el formulario por nosotros ahora mismo. La siguiente pregunta es, ¿cómo obtenemos los valores de entrada con Express?

Resulta que Express no maneja la lectura de datos del <form>elemento por sí solo. Tenemos que agregar otro paquete llamado body-parser para obtener esta funcionalidad.

npm install body-parser --save

Body-parser es un middleware . Ayudan a ordenar el requestobjeto antes de que los usemos. Express nos permite usar middleware con el usemétodo.

const express = require('express')
const bodyParser= require('body-parser')
const app = express()

// Make sure you place body-parser before your CRUD handlers!
app.use(bodyParser.urlencoded({ extended: true }))

// All your handlers here...
app.get('/', (req, res) => {/*...*/})
app.post('/quotes', (req, res) => {/*...*/})

El urlencodedmétodo dentro de body-parser le dice a body-parser que extraiga datos del <form>elemento y los agregue a la bodypropiedad en el requestobjeto.

Debería poder ver los valores del <form>elemento dentro req.body ahora. ¡Intente hacer un console.logy vea qué es!

app.post('/quotes', (req, res) => {
console.log(req.body)
})

Debería ver un objeto similar al siguiente:

Registra el cuerpo de la solicitud.

Hmmm.

¡El Maestro Yoda ha hablado! Asegurémonos de recordar las palabras de Yoda. Es importante. Queremos poder recuperarlo la próxima vez que carguemos nuestra página de índice.

Ingrese a la base de datos, MongoDB.

MongoDB

MongoDB es una base de datos. Podemos almacenar información en esta base de datos para recordar las palabras de Yoda. Luego, podemos recuperar esta información y mostrarla a las personas que ven nuestra aplicación.

Normalmente uso Mongoose (que es un marco para MongoDB) cuando uso MongoDB. En este artículo, le enseñaré cómo usar MongoDB básico. Si quieres aprender Mangosta, considera leer mi artículo sobre Mangosta .

Primero, necesitamos instalar MongoDB a través de npm.

npm install mongodb --save

Una vez instalado, podemos conectarnos a MongoDB a través del MongoClientmétodo de conexión como se muestra en el siguiente código:

const MongoClient = require('mongodb').MongoClient
MongoClient.connect('mongodb-connection-string', (err, client) => {
// ... do something here
})

La siguiente parte es obtener el enlace correcto a nuestra base de datos. La mayoría de las personas almacenan sus bases de datos en servicios en la nube como MongoDB Atlas . Vamos a hacer lo mismo también. (Es gratis).

También puede crear una base de datos en su computadora para el trabajo de desarrollo. Lea " Cómo configurar una conexión MongoDB local " para obtener instrucciones.

Configuración de MongoDB Atlas

Continúe y cree una cuenta en MongoDB Atlas . Una vez que haya terminado, debe crear una "Organización". Es como el nombre de una empresa. Puedes nombrarlo como quieras. (Puedes cambiarlo más tarde).

Crea una organización Atlas

También debe seleccionar un servicio en la nube. Continúe con MongoDB Atlas en este caso.

 
Selecciona un servicio en la nube.

A continuación, debe establecer permisos para los usuarios. MongoDB Atlas completará automáticamente su dirección de correo electrónico actual como usuario. Así que continúe con el siguiente paso.

Debería terminar con una pantalla que se ve así:

Pantalla del proyecto Atlas.

A continuación, debe crear una base de datos en MongoDB Atlas. Hay varios pasos para hacer esto.

Primero, necesita crear un nuevo proyecto. Puede hacer esto yendo a "Contexto" en el menú superior izquierdo. Haz clic en el menú desplegable. Luego, seleccione Nuevo proyecto.

Creando un nuevo proyecto.

A continuación, deberá nombrar su proyecto. Llámalo como quieras. Voy a llamar a esto star-wars.

Nombrar el proyecto.

Luego, deberá agregar miembros. Nuevamente, ya está agregado, así que continúe y haga clic en "Crear proyecto" para continuar.

Debería terminar con una pantalla que dice Create a Cluster.

Crear pantalla de clúster.

Haga clic en "Crear un clúster". Debería ver esta pantalla:

Seleccionar un clúster

Seleccione el clúster libre (opción de la izquierda) y continúe. Ahora debería ver una pantalla para configurar un clúster. Desplácese hacia abajo. Asegúrese de ver estas dos cosas:

  1. El nivel del clúster es M0 Sandbox
  2. El presupuesto mensual es GRATIS
Configuré el clúster.

Haga clic en Crear clúster a continuación. Debería ver "Se está creando su clúster".

Creando clúster.

Debe esperar aproximadamente 5 minutos para la creación del clúster. Cuando el clúster esté listo, verá esto:

Cluster listo

Ahora, necesitamos conectar nuestra aplicación Star Wars con este clúster.

Conexión a MongoDB Atlas

Haga clic en el botón Conectar.

Botón de conexión.

Debería aparecer un modal.

Conexión modal.

Debe incluir su dirección IP en la lista blanca antes de poder conectarse a su clúster. Esta es una característica de seguridad integrada en MongoDB Atlas. Continúe y haga clic en "Agregar su dirección IP actual".

Agrega la dirección IP.

A continuación, debe crear un usuario de MongoDB. Este nombre de usuario y contraseña son diferentes de los que utilizó para iniciar sesión en MongoDB Atlas. Este nombre de usuario y contraseña se utilizan SOLAMENTE para la base de datos.

Asegúrese de recordar el usuario y la contraseña de MongoDB. Lo usaremos para conectarnos a la base de datos.

Usuario de MongoDB.

A continuación, haga clic en elegir su método de conexión. Seleccione "Conectarse a su aplicación" y copie la cadena de conexión.

Elegir un método de conexión.
Copie la cadena de conexión.

La cadena de conexión debería verse así:

'mongodb+srv://<username>:<password>@<clustername>-rmp3c.mongodb.net/test?retryWrites=true&w=majority'

Necesita reemplazar 2 cosas aquí:

  1. Reemplazar <username>con su nombre de usuario de la base de datos
  2. Reemplazar <password>con la contraseña del usuario de la base de datos

En testla cadena de conexión apunta a una testbase de datos. Debería reemplazarlo testcon el nombre de su base de datos si usa Mongoose. Puede dejarlo como testsi usara MongoClient como lo que estamos haciendo en este tutorial.

Coloque esta cadena de conexión dentro del MongoClient.connect.

MongoClient.connect(connectionString, (err, client) => {
// ... do something here
}))

Sabemos que nos hemos conectado a la base de datos si no hay errores. Creemos una console.logdeclaración que diga "Conectado a la base de datos". Esto nos ayudará a saber que nos hemos conectado a la base de datos cuando reiniciemos el servidor.

MongoClient.connect(connectionString, (err, client) => {
if (err) return console.error(err)
console.log('Connected to Database')
})

Debería ver algo como esto:

Conectado a la base de datos.

Puede eliminar la advertencia de obsolescencia agregando la opción en MongoClient.connect

MongoClient.connect(connectionString, {
useUnifiedTopology: true
}, (err, client) => {
if (err) return console.error(err)
console.log('Connected to Database')
})
Conexión sin advertencia de obsolescencia.

MongoDB admite promesas. Si desea utilizar promesas en lugar de devoluciones de llamada, puede escribir MongoClient.connectasí. Se comporta exactamente como el código anterior.

MongoClient.connect(connectionString, { useUnifiedTopology: true })
.then(client => {
console.log('Connected to Database')
})
.catch(error => console.error(error))

Lea este artículo si desea obtener más información sobre las promesas en JavaScript.

Cambiar la base de datos

Necesitamos cambiar la base de datos de testotra. Puedes nombrarlo como quieras. Elegí nombrar mi nueva base de datos star-wars-quotesporque me ayuda a recordar lo que estoy construyendo.

MongoClient.connect(connectionString, { useUnifiedTopology: true })
.then(client => {
console.log('Connected to Database')
const db = client.db('star-wars-quotes')
})

MongoDB y servidor

Necesitamos la dbvariable de la conexión para acceder a MongoDB. Esto significa que debemos poner nuestros controladores de solicitudes exprés en la llamada de MongoClient then.

MongoClient.connect(/* ... */)
.then(client => {
// ...
const db = client.db('star-wars-quotes')
app.use(/* ... */)
app.get(/* ... */)
app.post(/* ... */)
app.listen(/* ... */)
})
.catch(console.error)

¡Finalmente podemos almacenar la cotización de Yoda en la base de datos ahora!

CRUD - CREAR (continuación)

Necesitamos crear un collectionantes de que podamos almacenar elementos en una base de datos. Aquí hay una analogía simple para ayudarlo a aclarar los términos en MongoDB:

  • Imagina que una base de datos es una habitación.
  • Una habitación contiene cajas ( collections).

Al igual que las bases de datos, puede nombrar colecciones como desee. En este caso, guardemos las cotizaciones en una quotescolección. Usamos db.collectionpara especificar la colección.

MongoClient.connect(/* ... */)
.then(client => {
// ...
const db = client.db('star-wars-quotes')
const quotesCollection = db.collection('quotes')

// ...
})

Podemos usar el insertOnemétodo para agregar elementos a una colección de MongoDB.

app.post('/quotes', (req, res) => {
quotesCollection.insertOne(req.body)
.then(result => {
console.log(result)
})
.catch(error => console.error(error))
})

Intente enviar el <form>desde el navegador. Debería ver un gran aspecto aterrador resulten la Terminal.

Publicar resultado.

Si ves esto, ¡felicidades! Ha agregado correctamente la cotización a la base de datos.

Puede verificar los elementos dentro de la base de datos yendo a "Colecciones" en MongoDB Atlas.

Colecciones en MongoDB Atlas.

Debería ver un documento en su base de datos. (Cada entrada de la base de datos se llama documento).

Documentos en MongoDB Atlas.

Si regresa al navegador, verá que todavía está intentando cargar algo.

El navegador sigue intentando cargar una página.

Esto sucede porque el navegador espera algo del servidor.

En este caso, no necesitamos enviar la información del navegador. Pidamos al navegador que redireccione de nuevo a /Hacemos esto con res.redirect.

app.post('/quotes', (req, res) => {
quotesCollection.insertOne(req.body)
.then(result => {
res.redirect('/')
})
.catch(error => console.error(error))
})
Redirigido.  El navegador ya no está esperando para cargar algo.

¡Hurra!

Ya que tenemos algunas citas en la colección, ¡mostrámoslas a nuestro usuario cuando lleguen a la página!

Mostrar cotizaciones a los usuarios (operación READ)

Necesitamos hacer dos cosas para mostrar cotizaciones de MongoDB Atlas a nuestros usuarios.

  1. Obtenga cotizaciones de MongoDB Atlas.
  2. Representar las citas en HTML con un motor de plantillas

Vayamos paso a paso.

Obtener cotizaciones de MongoDB

Podemos obtener cotizaciones que almacenamos en MongoDB con el findmétodo. Este método de mLab utiliza el findmétodo que está disponible en el collectionmétodo.

app.get('/', (req, res) => {
const cursor = db.collection('quotes').find()
console.log(cursor)
// ...
})

El findmétodo devuelve un cursorque no tendrá sentido si intentas registrarlo.

 
Objeto cursor de MongoDB

¡Pero este cursorobjeto contiene todas las citas de nuestra base de datos! Tiene un montón de métodos que nos permiten obtener nuestros datos. Por ejemplo, podemos usar toArraypara convertir los datos en una matriz.

app.get('/', (req, res) => {
db.collection('quotes').find().toArray()
.then(results => {
console.log(results)
})
.catch(error => console.error(error))
// ...
})
 

¡Excelente! ¡Vemos las citas que agregamos! (Ves tantas citas iguales porque las agregué todas al escribir este tutorial 😆).

A continuación, queremos generar un HTML que contenga todas nuestras citas.

Renderizando el HTML

No podemos servir el index.htmlarchivo y esperar que las citas aparezcan mágicamente porque no hay forma de agregar contenido dinámico a un archivo HTML.

Lo que podemos hacer, en cambio, es usar un motor de plantillas para generar el HTML. Los motores de plantilla más populares incluyen Pug , Embedded JavaScript y Nunjucks .

He escrito extensamente sobre el cómo y el por qué de los motores de plantilla en una publicación separada . Es posible que desee comprobarlo si no tiene idea de qué son los motores de plantilla.

Utilizo Nunjucks como mi motor de plantillas preferido. Siéntete libre de revisar la publicación para descubrir por qué.

Para este tutorial, usaremos Embedded JavaScript (EJS) como nuestro motor de plantillas porque es el más fácil para empezar. Le resultará familiar desde el principio, ya que estará escribiendo HTML y JavaScript.

Usando EJS

Primero, necesitamos instalar EJS.

npm install ejs --save

A continuación, debemos establecerlo view engineen ejsEsto le dice a Express que estamos usando EJS como motor de plantilla. Puede que tenga que colocar antes de cualquier app.useapp.getapp.postmétodos.

app.set('view engine', 'ejs')

// Middlewares and other routes here...

Ahora podemos generar HTML que contiene las comillas . Este proceso se denomina renderización del HTML.

Usaremos el rendermétodo integrado en Express responseDebe seguir la siguiente sintaxis:

res.render(view, locals)
  • viewes el nombre del archivo que estamos renderizando. Este archivo debe colocarse dentro de una viewscarpeta.
  • localsson los datos que se pasan al archivo.

Creemos una vista. Crearemos un index.ejsarchivo dentro de la carpeta de vistas.

mkdir views
touch views/index.ejs

Copiaremos / pegaremos todo desde index.htmlen index.ejs.

<!-- index.ejs -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Star Wars Quote App</title>
</head>

<body>
<h1>May Node and Express be with you.</h1>

<form action="/quotes" method="POST">
<input type="text" placeholder="name" name="name" />
<input type="text" placeholder="quote" name="quote" />
<button type="submit">Submit</button>
</form>
</body>
</html>

A continuación, usaremos res.renderpara renderizar este index.ejsarchivo.

app.get('/', (req, res) => {
db.collection('quotes').find().toArray()
.then(/* ... */)
.catch(/* ... */)
res.render('index.ejs', {})
})

Si actualiza la página, debería seguir viendo lo mismo. Nada debería cambiar, nada debería romperse.

Genera un archivo ejs.

Pongamos las comillas en index.ejsPara hacer esto, necesitamos pasar las comillas al rendermétodo.

app.get('/', (req, res) => {
db.collection('quotes').find().toArray()
.then(results => {
res.render('index.ejs', { quotes: results })
})
.catch(/* ... */)
})

En index.ejs, podemos usar variables de lugar entre las etiquetas <%=%>Intentemos poner quotesen el HTML:

<!-- In index.ejs -->
<body>
<h1> ... </h1>
<form> ... </form>
<%= quotes %>
</body>

Deberías ver esto:

Citas renderizadas en EJS.

Vemos muchos [object Object]porque cada cita dentro resultses un objeto JavaScript. ejsno puede convertir ese objeto en HTML automáticamente.

Necesitamos recorrer las comillas. Podemos hacer esto con un forbucle. En EJS, escribimos un bucle for como escribimos un forbucle JavaScript La única diferencia es que necesitamos colocar las fordeclaraciones de bucle entre <%%>.

<h2> Quotes </h2>

<ul class="quotes">
<!-- Loop through quotes -->
<% for(var i = 0; i < quotes.length; i++) {%>
<li class="quote">
<!-- Output name from the iterated quote object -->
<span><%= quotes[i].name %></span>:
<!-- Output quote from the iterated quote object -->
<span><%= quotes[i].quote %></span>
</li>
<% } %>
</ul>
Cotizaciones renderizadas con EJS.

CRUD - ACTUALIZAR

Usamos la operación UPDATE cuando queremos cambiar algo. Puede activarse con una solicitud PUT . Me gusta POSTPUTse puede activar mediante JavaScript o mediante un <form>elemento.

Cambiemos las cosas y usemos JavaScript, ya que ya sabe cómo usar los <form>elementos.

Para esta operación de actualización, crearemos un botón que reemplaza la primera cita de Yoda por algo escrito por Darth Vadar.

Para hacer esto, necesitamos agregar un buttonen el index.ejsarchivo:

<div>
<h2>Darth Vadar invades!</h2>
<p>
Replace first Yoda's quote with a quote written by Darth Vadar
</p>
<button id="update-button">Replace Yoda's quote</button>
</div>
Agregue la sección de actualización a HTML.

También crearemos un archivo JavaScript externo para ejecutar una PUTsolicitud. Según las convenciones Express, este JavaScript se guarda en una carpeta llamadapublic

$ mkdir public
$ touch public/main.js

Luego, tenemos que decirle a Express que haga que esta publiccarpeta sea accesible para el público mediante el uso de un middleware incorporado llamadoexpress.static

app.use(express.static('public'))

Ahora podemos agregar el main.jsarchivo al index.ejsarchivo:

<body>
<!-- ... -->
<script src="/main.js"></script>
</body>

Enviaremos una PUTsolicitud cuando se haga clic en el botón. Esto significa que necesitamos escuchar un clickevento.

A continuación, enviaremos la solicitud PUT cuando se haga clic en el botón:

// main.js
const update = document.querySelector('#update-button')

update.addEventListener('click', _ => {
// Send PUT Request here
})

Envío de una solicitud PUT

La forma más sencilla de activar una solicitud PUT en los navegadores modernos es utilizar la API Fetch .

Fetch tiene la siguiente sintaxis:

fetch(endpoint, options)

En este caso, digamos que queremos enviar la solicitud a /quotesNos pondremos endpointen /quotes.

update.addEventListener('click', _ => {
fetch('/quotes', {/* ... */})
})

Necesitamos enviar una PUTsolicitud esta vez. Podemos hacer esto configurando el método de Fetch en put.

update.addEventListener('click', _ => {
fetch('/quotes', {
method: 'put'
})
})

Las aplicaciones modernas envían datos JSON a los servidores. También reciben datos JSON a los servidores. JSON son las siglas de JavaScript Object Notation. Son como objetos de JavaScript, pero cada propiedad y valor se escriben entre dos comillas.

A continuación, se muestra un ejemplo de datos de JavaScript:

const data = {
name: 'Darth Vadar',
quote: 'I find your lack of faith disturbing.'
}

Y cómo se ve su contraparte JSON. (Fíjate como todo se envuelve entre dos ").

{
"name": "Darth Vadar",
"quote": "I find your lack of faith disturbing."
}

Necesitamos decirle al servidor que estamos enviando datos JSON configurando los Content-Typeencabezados en application/json.

update.addEventListener('click', _ => {
fetch('/quotes', {
method: 'put',
headers: { 'Content-Type': 'application/json' },
})
})

A continuación, necesitamos convertir los datos que enviamos a JSON. Podemos hacer esto con JSON.stringifyEstos datos se pasan a través de la bodypropiedad.

update.addEventListener('click', _ => {
fetch('/quotes', {
method: 'put',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'Darth Vadar',
quote: 'I find your lack of faith disturbing.'
})
})
})

Aceptando la solicitud PUT

Nuestro servidor aún no acepta datos JSON. Podemos enseñar a leer JSON mediante la adición de la body-parser's jsonmiddleware.

app.use(bodyParser.json())

A continuación, podemos manejar la PUTsolicitud con un putmétodo. Debería poder ver los valores que enviamos desde la solicitud de recuperación.

app.put('/quotes', (req, res) => {
console.log(req.body)
})
Ponga el cuerpo de la solicitud

El siguiente paso es cambiar la primera cita de Yoda por esta cita de Darth Vadar.

Cambiar la cita de Yoda

Las colecciones de MongoDB vienen con un método llamado findOneAndUpdateEste método nos permite buscar y cambiar un elemento en la base de datos. Tiene la siguiente sintaxis:

quotesCollection.findOneAndUpdate(
query,
update,
options
)
.then(result => {/* ... */})
.catch(error => console.error(error))

querynos permite filtrar la colección con pares clave-valor. Si queremos filtrar las comillas a las escritas por Yoda, podemos establecer { name: 'Yoda' }como consulta.

quotesCollection.findOneAndUpdate(
{ name: 'Yoda' },
update,
options
)
.then(result => {/* ... */})
.catch(error => console.error(error))

update, le dice a MongoDB qué cambiar. Utiliza los operadores de actualización de MongoDB como $set$inc$push.

Usaremos el $setoperador ya que estamos cambiando las citas de Yoda por las de Darth Vadar:

quotesCollection.findOneAndUpdate(
{ name: 'Yoda' },
{
$set: {
name: req.body.name,
quote: req.body.quote
}
},
options
)
.then(result => {/* ... */})
.catch(error => console.error(error))

options le dice a MongoDB que defina opciones adicionales para esta solicitud de actualización.

En este caso, es posible que no existan citas de Yoda en la base de datos. Podemos obligar a MongoDB a crear una nueva cita de Darth Vadar si no existen citas de Yoda. Hacemos esto estableciendo upserten trueupsertsignifica: Insertar un documento si no se puede actualizar ningún documento.

quotesCollection.findOneAndUpdate(
{ name: 'Yoda' },
{
$set: {
name: req.body.name,
quote: req.body.quote
}
},
{
upsert: true
}
)
.then(result => {/* ... */})
.catch(error => console.error(error))

Finalmente, iniciemos sesión resulten la línea de comandos.

app.put('/quotes', (req, res) => {
quotesCollection.findOneAndUpdate(/* ... */)
.then(result => {
console.log(result)
})
.catch(error => console.error(error))
}

Intente hacer clic en el botón "reemplazar la primera cita de Yoda" en el navegador. Debería ver este resultado en su línea de comando. Esto dice que cambiamos una cita de Yoda.

Poner resultado.

Si actualiza el navegador, debería ver la cita de Darth Vadar como primera cita.

Comprobación del HTML después de una solicitud PUT.

¿Te findOneAndUpdateparece complicado? Bueno, ES complicado. Es por eso que uso Mongoose en lugar de MongoDB. Puede obtener más información sobre Mongoose en este artículo .

Finalmente, debemos responder al JavaScript que envió la PUTsolicitud. En este caso, simplemente enviaremos el successmensaje.

app.put('/quotes', (req, res) => {
quotesCollection.findOneAndUpdate(/* ... */)
.then(result => {
res.json('Success')
})
.catch(error => console.error(error))
}

A continuación, podemos manejar la respuesta del servidor a través de un thenobjeto. (Hacemos esto porque fetchdevuelve una promesa). Sin embargo, Fetch es ligeramente diferente a la mayoría de las promesas. Necesita usar otro thenobjeto para obtener la respuesta del servidor.

Esto es lo que debe hacer:

fetch({ /* request */ })
.then(res => {
if (res.ok) return res.json()
})
.then(response => {
console.log(response)
})

Debería poder ver un Successmensaje del servidor en la consola.

Respuesta del servidor.

Escribí un artículo sobre la API de Fetch si se pregunta por qué necesitamos dos thenllamadas. ¡Dale una lectura! Ayudará a cimentar su comprensión.

Si está trabajando en una aplicación web elegante, puede usar JavaScript para actualizar el DOM, de modo que los usuarios vean los nuevos cambios de inmediato.

Sin embargo, la actualización del DOM está fuera del alcance de este artículo, por lo que solo actualizaremos el navegador para ver los cambios.

fetch({ /* request */ })
.then(res => {
if (res.ok) return res.json()
})
.then(response => {
window.location.reload(true)
})

Si desea aprender a usar JavaScript para actualizar el DOM, le sugiero que siga mi curso Learn JavaScript . ¡Incluso te enseño cómo hacer que tu interfaz sea rápida y ágil! (Verifique el componente Todolist).

¡Eso es todo para la operación ACTUALIZAR ! Pasemos a eliminar.

CRUD - BORRAR

La operación DELETE se puede activar mediante una solicitud DELETE . Es similar a la UPDATEsolicitud, por lo que debería ser simple si comprende lo que hemos hecho anteriormente.

Para ello, eliminemos la primera cita de Darth Vadar.

Primero, necesitamos agregar un botón de eliminación a index.ejs.

<div>
<h2>Remove Darth Vadar!</h2>
<p>
Delete one Darth Vadar's quote. Does nothing if there are no more Darth
Vadar's quote
</p>
<button id="delete-button">Delete Darth Vadar's quote</button>
</div>
Agrega el botón de eliminar al archivo index.ejs.

Luego, activaremos una solicitud DELETE a través de Fetch cuando un usuario haga clic en el botón Eliminar.

const deleteButton = document.querySelector('#delete-button')

deleteButton.addEventListener('click', _ => {
fetch('/quotes', {
method: 'delete',
})
})

Dado que estamos eliminando una cotización de Darth Vadar, solo necesitamos enviar el nombre de Darth Vadar al servidor.

deleteButton.addEventListener('click', _ => {
fetch(/* ... */, {
method: 'delete',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'Darth Vadar'
})
})
.then(res => {
if (res.ok) return res.json()
})
.then(data => {
window.location.reload()
})
})

Luego podemos manejar el evento en nuestro lado del servidor con el deletemétodo:

app.delete('/quotes', (req, res) => {
// Handle delete event here
})

Eliminar un documento de MongoDB

Las colecciones de MongoDB tienen un método llamado deleteOneNos permite eliminar un documento de la base de datos. Toma dos parámetros: queryoptions.

quotesCollection.remove(
query,
options
)
.then(result => {/* ... */})
.catch(error => console.error(error))

queryfunciona como queryen findOneAndUpdateNos permite filtrar la colección a las entradas que estamos buscando. En este caso, podemos configurar nameDarth Vadar.

quotesCollection.remove(
{ name: 'Darth Vadar' },
options
)
.then(result => {/* ... */})
.catch(error => console.error(error))

Sin embargo, dado que ya pasamos el nombre Darth Vadarde Fetch, ya no necesitamos codificarlo en Express. Simplemente podemos usar req.body.name.

app.delete('/quotes', (req, res) => {
quotesCollection.remove(
{ name: req.body.name },
options
)
})

En este caso, no necesitamos cambiar ninguna opción, por lo que podemos omitir options.

app.delete('/quotes', (req, res) => {
quotesCollection.deleteOne(
{ name: req.body.name }
)
})

Luego, podemos enviar una respuesta al JavaScript en la thenllamada.

app.delete('/quotes', (req, res) => {
quotesCollection.deleteOne(
{ name: req.body.name }
)
.then(result => {
res.json(`Deleted Darth Vadar's quote`)
})
.catch(error => console.error(error))
})

Ahora, cuando haga clic en el botón Eliminar, el navegador enviará la solicitud DELETE a través de Fetch a nuestro servidor Express. Luego, el servidor responde enviando un error o un mensaje.

¿Qué pasa si no hay más citas de Darth Vadar?

Si no hay más citas de Darth Vadar, las result.deletedCounthabrá 0Podemos enviar un mensaje que diga al navegador que no hay más citas de Darth Vadar para eliminar.

app.delete('/quotes', (req, res) => {
quotesCollection.deleteOne(/* ... */)
.then(result => {
if (result.deletedCount === 0) {
return res.json('No quote to delete')
}
res.json(`Deleted Darth Vadar's quote`)
})
.catch(error => console.error(error))
})

Si JavaScript recibe una No quote to deleterespuesta, podemos decirle al usuario que no hay una cita de Darth Vadar para eliminar.

Para hacer esto, agreguemos un elemento donde podamos informar a los usuarios sobre este mensaje.

<div id="message"></div>

Si recibimos No quote to delete, podemos cambiar el textContentde este .messagediv.

const messageDiv = document.querySelector('#message')

deleteButton.addEventListener('click', _ => {
fetch(/* ... */)
.then(/* ... */)
.then(response => {
if (response === 'No quote to delete') {
messageDiv.textContent = 'No Darth Vadar quote to delete'
} else {
window.location.reload(true)
}
})
.catch(/* ... */)
})
Mensaje si no se pueden eliminar comillas.

¡Eso es todo para la operación DELETE !

Haz que se vea mejor ...

El último paso es hacer que la aplicación se vea un poco mejor rociando algunos estilos.

Agrega CSS para que la aplicación se vea mejor.

Terminando

Cubrimos MUCHO en este mega tutorial. Aquí hay una lista de cosas que hemos hecho juntos:

  1. Entendido para qué se utilizan Express, Node y MongoDB
  2. Entendido CRUD
  3. Operaciones de creación, lectura, actualización y eliminación ejecutadas
  4. Creó una cuenta Atlas para MongoDB
  5. Guardar, leer, actualizar y eliminar de MongoDB
  6. Mostrar datos variables con motores de plantilla

Ahora ha aprendido todo lo que necesita saber sobre la creación de aplicaciones simples con Node, Express y MongoDB. Ahora, adelante y crea más aplicaciones, joven padawan. Que la fuerza esté con usted.

Publicar un comentario

0 Comentarios