Una lista de tareas pendientes es una aplicación para principiantes que hacen muchos estudiantes de programación. Es una lista de tareas que necesita hacer en un día. Puede agregarle tareas e incluso eliminarlas cuando haya terminado con ellas. A menudo, se puede ver que muchos tutoriales dejan la aplicación de la lista de tareas solo en la parte frontal. El lector nunca llega a saber cómo integrarlo con el backend, de modo que se utilice una base de datos adecuada y los datos no se pierdan al actualizar/reiniciar. Este artículo busca enseñarte cómo hacer un proyecto completo de lista de tareas pendientes.
Este artículo está dirigido a la audiencia que ha adquirido conocimientos básicos de desarrollo web pero que no ha creado ningún proyecto. Muchos estudiantes conocen la sintaxis pero no pueden hacer aplicaciones. El solo hecho de conocer cierta tecnología como Nodejs no es suficiente, también se requiere poder usarla con otras tecnologías y construir una aplicación usando la lógica de programación. Este artículo está hecho para ayudar a esas personas a mejorar sus conocimientos mediante la construcción de proyectos.
Características de nuestra aplicación:
- Frontend dinámico, a través de EJS, que es un paquete NPM.
- Backend construido con Nodejs.
- Base de datos utilizada: MongoDB Atlas.
Cómo funciona la aplicación:
- Se representa una página de inicio donde el usuario puede ver sus tareas y también insertar una nueva tarea.
- Se envía una nueva solicitud al lado del servidor cuando hacemos clic en el botón Agregar.
- Se envía una nueva solicitud de eliminación del elemento cuando lo verificamos, una vez que se completa la tarea.
Nota: este artículo se centrará principalmente en el backend, por lo que no se proporcionarán explicaciones detalladas de la parte frontal, es decir, HTML y CSS, aunque se proporcionará el código.
Comencemos con la implementación paso a paso.
Paso 1: abre una carpeta vacía en VS Code. Cree un archivo con el índice de nombre .js dentro de esta carpeta.
Paso 2: escriba el siguiente comando en la terminal para inicializar esta carpeta para hacer un proyecto de Nodejs.
npm init
Paso 3: Luego de esto, escribe el siguiente comando para instalar algunos paquetes que estaremos usando en nuestra aplicación:
npm install –save express ejs body-parser mongodb mongoose
Explicación: Los comandos anteriores instalan los paquetes necesarios, que son necesarios en nuestra aplicación.
- ejs para renderizar contenido en la interfaz.
- express es un marco de Nodejs utilizado para ayudar en la redundancia de código.
- analizador de cuerpo para leer datos de requests entrantes.
- mongodb por poder usar bases de datos y mongoose es su marco para redundancia de código y fácil conexión.
Ahora cree dos carpetas al lado de nuestra app.js, nómbrelas como públicas (para los archivos que queremos mostrar al usuario) y vistas (para los archivos EJS).
Estructura del proyecto: Tendrá el siguiente aspecto.
Paso 4: Ahora abra su archivo index.js. En este archivo, vamos a codificar nuestro servidor. Donde manejamos las requests que provienen del navegador, administramos los datos en ellos y respondemos en consecuencia. Trataremos dos tipos de requests, que son las más utilizadas, get y post. Obtener solicitud es para leer del servidor y publicar solicitud por escrito en el servidor. También definiremos en qué puerto de nuestra máquina se accede al servidor de esta aplicación. Este es el archivo donde existe toda la lógica de nuestra aplicación. Incluso nos conectamos a una base de datos en la nube en este archivo.
index.js
// To use the packages installed, we import // them using require and save them in // a constant const express = require("express"); const bodyParser = require("body-parser"); const ejs = require("ejs"); const mongoose = require("mongoose"); // Initializing a constant to use express // methods and create middlewares. const app = express(); // Telling Node.js to use body-parser for // reading data coming from our // incoming requests in URL app.use(bodyParser.urlencoded({ extended: true })); // Telling Nodejs that all our static // files(here: CSS files) are // stored in public folder app.use(express.static("public")); // Telling Nodejs that we will write our // frontend in ejs files. Thus viewing // engine has to be set to use ejs app.set("view engine", "ejs");
Explicación: Incluimos los paquetes instalados en algunas constantes para usar en nuestra aplicación. app es la constante a través de la cual creamos nuestro middleware e inicializamos paquetes para usar en nuestra aplicación. Primero, el analizador corporal se inicializa para decirle a Nodejs que use el analizador corporal para leer datos. la carpeta pública se declara estática para decirle a Nodejs que aquí es donde se encuentran nuestros archivos estáticos (por ejemplo, CSS e imágenes). Y por último, ejs se configura como un motor de visualización para que podamos escribir nuestro código de interfaz en archivos ejs .
Nota: No requerimos mongodb , ya que mongoose se encarga de ello.
Paso 5: Ahora vamos a conectar nuestra aplicación con la base de datos en la nube, MongoDB Atlas y definir la estructura básica de nuestra colección . Definimos cuál es el tipo de datos que almacenamos y otras características asociadas a los mismos.
index.js
// Make sure you did not use any special // characters(e.g. @) in your user-name // or password mongoose.connect( "mongodb+srv://<name>:<password>@cluster0.38u1b.mongodb.net/todoDB"); // Defining the schema or structure of // a single item in mongodb const taskSchema = { name: { type: String, required: true } }; // Using the following code, node.js // creates a collection named // 'tasks' using the taskSchema const Task = mongoose.model("Task", taskSchema);
Explicación: aquí usamos nuestra constante mongoose para conectarnos a nuestra base de datos pasando el enlace para conectar el método en el objeto constante mongoose. Luego, describimos el modelo de nuestro elemento en mongodb , donde establecemos su tipo de datos como String. El método del modelo utiliza este modelo para crear una colección con los elementos de nombre. Necesitamos escribir una palabra singular con un título como se muestra, mongoose lo convierte automáticamente en un caso pequeño y una palabra en plural. La palabra «todoDB» al final de la URL de nuestra base de datos es el nombre que le doy a la base de datos. Puedes usar cualquier otra palabra si quieres.
La URL de nuestra base de datos se recibe a través de los siguientes pasos desde nuestra cuenta de MongoDB Atlas:
- Haga clic en el botón Conectar.
- Elige la segunda Opción: Conecta tu Aplicación.
- Copie el formato de URL.
Paso 6: Ahora trabajamos en nuestras requests. La primera solicitud en la que trabajamos es la solicitud de nuestra página de inicio, enviada a la URL: “/”. Aquí escribimos el código donde servimos nuestra página de inicio a la ruta o ruta de nuestra página de inicio, que es “/” para cualquier sitio web. La página de inicio simplemente muestra todas nuestras tareas. En esta aplicación, es la única página web que tenemos, ya que no es necesario tener ninguna otra página.
index.js
app.get("/", function (req, res) { // Getting today's date to display // on top of our to-do let today = new Date(); let options = { weekday: "long", day: "numeric", month: "long" }; // If we do not use the first argument // in below line, which is "en-US" we get // date in form of numbers only, separated // with a /, thus the day won't be known let day = today.toLocaleDateString("en-US", options); // Find is a function given by mongoose, which // is applied to a collection, it returns // all the documents found in it. Task.find({}, function (err, foundTasks) { if (err) { console.log(err) } else { // Render the file names index.ejs and // send the object to with the following // data, sent as second parameter, in // which we send date // and tasks found in database. res.render("index", { today: day, tasks: foundTasks }); } }) });
Explicación: La solicitud de obtención es para leer datos, cuando se ingresa la URL de nuestra aplicación en el navegador, la solicitud de obtención se envía a la ruta «/», que es nuestra página de inicio para leer y ver el contenido de nuestra página de inicio. app.get() dice que debe ejecutarse cuando se recibe una solicitud de obtención en «/», ejecutando la devolución de llamada dentro de él. find es un método definido por mongoose en cada colección para encontrar documentos en esa colección. Se pasa un objeto vacío a esta función de búsqueda para indicar que no hay ninguna condición que el documento encontrado tenga que coincidir, por lo tanto, significa que todos los documentos deben recuperarse. El resultado que devuelve esta función si no se encuentra ningún error es una array de objetos. En el objeto de respuesta, llamamos a la función render que toma el nombre de ejsarchivo para enviar y un objeto de valores para enviar a la interfaz.
Paso 7: Ahora vamos a nuestra carpeta de “vistas” y creamos un archivo ejs , index.ejs . Aquí definimos la estructura de nuestra página web, usando código HTML. También escribimos algo de lógica Javascript que mantiene la representación dinámica de nuestra aplicación. Esta representación dinámica simplemente muestra la tarea recién agregada en nuestra página sin que el usuario vuelva a cargar la página.
index.ejs
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content= "width=device-width, initial-scale=1.0"> <title>To-do List</title> <link rel="stylesheet" href="css/styles.css"> </head> <body> <div class="box" id="heading"> <h1 style="color: #ffffff"> <%= today %> </h1> </div> <div class="box"> <!-- We check if the object receieved is not empty, else there will be an error --> <!-- To avoid error, we simply use if-else, empty object is handled in if block --> <% if (tasks.length===0) {%> <p style="text-align: center;"> No Task Added Yet </p> <% } else { %> <% for (var i=0; i< tasks.length; i++){ %> <!-- Action is the route to which form send request --> <!-- And method defines the "type" of request --> <form action="/delete" method="post"> <div class="item"> <input type="checkbox" name="checkbox" value="<%=tasks[i]._id%>" onchange="this.form.submit()"> <p> <%= tasks[i].name %> </p> </div> <hr> </form> <% } %> <% } %> <!-- Action is the route to which form send request --> <!-- And method defines the "type" of request --> <form class="item " action="/" method="POST"> <input type="text" name="newTask" autocomplete="off" placeholder="Add a New Task Here"> <button type="submit" name="submit">+</button> </form> </div> </body> </html>
Explicación: La sintaxis de ejs es similar a HTML. Las declaraciones de Javascript se escriben dentro de <% %> y las variables se escriben dentro de <%= %>. Esta capacidad de usar Javascript con HTML permite que ejs tenga una función de representación dinámica. En este archivo ej s, primero verificamos si la array recibida está vacía o no, si no lo está, luego recorremos esta array de objetos y usamos un operador de punto en cada objeto para mostrar su nombre. También colocamos una casilla de verificación junto al nombre del elemento dentro de un formulario que envía una solicitud de publicación en la ruta «/ eliminar» , y establecemos su valor en la identificación del objeto, que es proporcionada por MongoDB. El id se escribe como _iden MongoDB. Queremos que se envíe una solicitud cuando marcamos la casilla de verificación, por lo tanto, el formulario se envía mediante la función de envío.
NOTA: Asegúrese de que el nombre de la variable coincida con la clave del objeto enviado a la interfaz desde Nodejs mientras procesa ejs.
Paso 8: En el archivo styles.css, escribimos nuestro código CSS, lo que le da un buen aspecto a nuestra página de inicio. Hace que el contenedor principal y el encabezado de nuestra página aparezcan en el centro, definimos los temas de color que queremos usar y también diseñamos nuestra fuente, botón y otros elementos en nuestra página.
styles.css
*{ font-family: cursive; box-sizing: border-box; } h1 { padding: 10px; } .box { max-width: 450px; margin: 20px auto; background: white; border-radius: 5px; box-shadow: 7px 7px 15px 5px rgba(0, 0, 0, 0.3); } #heading { background-color: #353434; text-align: center; } .item { min-height: 70px; display: flex; align-items: center; border-bottom: 1px solid #F1F1F1; } .item:last-child { border-bottom: 0; } input:checked+p { text-decoration: line-through; text-decoration-color: #353434; } input[type="checkbox"] { appearance: none; margin: 20px; height: 25px; width: 25px; border: 2px solid black; border-radius: 3px; } input[type="checkbox"]:hover, input[type="checkbox"]:focus{ transform: scale(1.2); background-color: #353434; color: white; cursor: pointer; } input[type="checkbox"]:checked{ clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%); } p { text-align: left; margin: 0; padding: 20px; font-size: 1.8rem; font-weight: bold; color: #353434; text-shadow: 2px 2px gray; } form { text-align: center; padding: 10px; } button { width: 50px; height: 50px; border-radius: 50%; font-size: 1.5rem; background-color: #494848; border-top: 4px solid white; border-left: 4px solid white; border-bottom: 4px solid black; border-right: 4px solid black; color: white; } button:hover{ cursor: pointer; color: #494848; background-color: white; border: 3px solid #494848; box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.459); } input[type="text"] { margin: 5px; text-align: center; height: 50px; background: transparent; font-size: 20px; font-weight: 200; width: 100%; border: none; border-bottom: 4px solid #494848; } input[type="text"]:focus { outline: none; border: 2px solid #494848; border-bottom: 4px solid #494848; border-radius: 5px; box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.301); }
Paso 9: Ahora trabajamos en las rutas para agregar un elemento. Volvemos a nuestro archivo index.js. Ahora escribiremos el código que lee los datos entrantes desde la interfaz, los guarda en la base de datos como una nueva tarea y luego los redirige a la página de inicio una vez que la tarea se agrega con éxito. También verificamos si los datos entrantes, aquí la tarea, no están vacíos.
index.js
app.post("/", function (req, res) { const taskName = req.body.newTask; if (taskName) { const task = new Task({ name: taskName, }); // Save the task using save method provided // by mongoose. It returns a promise, in // which we re-direct to home page. we write // it in then block to make sure that // we are redirected only when the save // method finished executing without any // error. Otherwise the item will be saved, // after we were redirected, thus, it will look // like the task was not added and thus we // will have to reload to see the newly added // task. Which can be exhausting. task.save() .then(() => { res.redirect("/"); }); } else { res.redirect("/"); } });
Explicación: Al igual que creamos un objeto de una clase, creamos un documento de la colección usando la nueva palabra clave. Luego llamamos al método save() en la constante itemName, que lo guarda en nuestra base de datos. Se lee usando el objeto de solicitud, luego se accede a su cuerpo y luego al nombre de la entrada usando el operador de punto como si se accediera a objetos anidados. Esta función también la proporciona la mangosta. También estamos comprobando si el nombre del elemento está vacío o no. Si está vacío, redirigimos a casa y si no, lo guardamos y luego redirigimos a casa. Luego, nuevamente Nodejs recibe la solicitud de la página de inicio, que es «/» y ejecuta el middleware para ello. Esta vez se encuentra un nuevo elemento y, por lo tanto, la array que envía a la interfaz se actualiza, lo que da como resultado la actualización de nuestra página. Así es como se establece el renderizado dinámico en nuestra aplicación.
Paso 10: Y por último, trabajamos en nuestra solicitud de eliminación que se envía cada vez que hacemos clic en la casilla de verificación. La página se volverá a cargar cuando hagamos clic en una casilla de verificación, tiene en la interfaz que está escrito dentro de un formulario, que se envía automáticamente una vez que se envía una casilla de verificación, debido a la función que se le pasó, y envía la identificación de la tarea que se coloca junto a. El siguiente código lee la identificación y encontrará la tarea de la base de datos que tiene esta identificación, la eliminará y la redirigirá a la página de inicio una vez que se complete la tarea.
index.js
app.post("/delete", function (req, res) { const checkedItemId = req.body.checkbox; Task.findByIdAndRemove(checkedItemId, function (err) { if (!err) { console.log("Successfully deleted checked item."); res.redirect("/"); } }); });
Explicación: en el atributo de acción de nuestro formulario, usamos «/ eliminar» como la dirección a la que se envía la solicitud y el valor del atributo de método se establece como «POST» . Dentro de este formulario está la casilla de verificación que envía el formulario cuando hacemos clic en él. Ahora, esta solicitud con método de publicación se recibe en app.post() . Almacenamos la identificación del objeto que se envía desde la interfaz, luego, en la recopilación de elementos, llamamos a un método proporcionado por mongoose para encontrar un documento que tenga la misma identificación que el recibido y lo eliminamos. Toma una identificación y una devolución de llamada como argumentos. La devolución de llamada se ejecuta cuando se elimina el elemento.
Paso 11: Finalmente, escribimos un código que hace que nuestra aplicación sea accesible desde uno de los puertos de la máquina. Se llama escuchar.
Javascript
app.listen(process.env.PORT || 3000, function () {console.log(“Server running at port 3000”);});
Explicación: Este es el código que escribimos al final. El método de escucha se llama en nuestro objeto de aplicación para escuchar un puerto en nuestra computadora. Aquí usamos 3000, también puede usar algún otro puerto. process.env.PORT es el puerto que utiliza el servicio en el que se aloja nuestra aplicación. El puerto que usarán no necesita ser el mismo que usamos durante nuestro desarrollo.
Ahora veamos el código completo.
index.js
const express = require("express"); const bodyParser = require("body-parser"); const ejs = require("ejs"); const mongoose = require("mongoose"); const app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.use(express.static("public")); mongoose.connect( "mongodb+srv://<username>:<password>@cluster0.g6nae.mongodb.net/todolistDB"); const taskSchema = { name: { type: String, required: true } }; const Task = mongoose.model("Task", taskSchema); app.set("view engine", "ejs"); app.get("/", function (req, res) { let today = new Date(); let options = { weekday: "long", day: "numeric", month: "long" }; let day = today.toLocaleDateString("en-US", options); Task.find({}, function(err, foundTasks){ if (err){ console.log(err) } else { res.render("index", { today: day, tasks: foundTasks }); } }) }); app.post("/", function (req, res) { const taskName = req.body.newTask; if(taskName){ const task = new Task({ name: taskName, }); task.save().then(()=>{ res.redirect("/"); }); } else{ res.redirect("/"); } }); app.post("/delete", function (req, res) { const checkedItemId = req.body.checkbox; Task.findByIdAndRemove(checkedItemId, function (err) { if (!err) { console.log("Successfully deleted checked item."); res.redirect("/"); } }); }); app.listen(process.env.PORT || 3000, function () { console.log("Server running at port 3000"); });
Paso para ejecutar la aplicación: Para ejecutar la aplicación, abra la terminal y escriba el comando.
Node index.js
Salida: Abra el navegador y en su cuadro de dirección URL, escriba: localhost:3000.
Ahora comprendamos cómo implementar la aplicación creada anteriormente.
Paso 1: Ve al sitio web de Heroku. http://www.heroku.com/
Paso 2: Regístrese si aún no tiene una cuenta.
Paso 3: complete el formulario de registro
Una vez completada la inscripción, verá una página como esta:
Obtiene una página de inicio:
Paso 4: Instale la CLI de Heroku según su sistema operativo:
Paso 5: abra la CLI de su sistema o el terminal VS Code en el directorio del proyecto actual. Inicie sesión en Heroku usando el comando de terminal:
iniciar sesión heroku
Paso 6: Se abre una ventana del navegador, haga clic en el botón de inicio de sesión y listo.
Nota: Dado que acabamos de crear una cuenta y tenemos Heroku abierto en nuestro navegador, nos reconoce y no solicita credenciales para iniciar sesión. iniciar sesión
Paso 7: luego inicializa git en nuestro proyecto. (asegúrese de tener git instalado en su sistema informático: https://git-scm.com/downloads ): escriba el comando.
iniciar git
Paso 8: Agregue un archivo .gitignore y un Procfile usando los siguientes comandos:
toque .gitignore
El archivo .gitignore se crea para enumerar todos los archivos y carpetas que no deben incluirse en nuestro repositorio. Se trata principalmente de la carpeta node_modules , ya que se puede crear en cualquier lugar escribiendo el comando: npm install . Este comando lee el archivo packages.json y el archivo packages-lock.json que contienen la información de los paquetes instalados y se instala en el directorio automáticamente.
Paso 9: Ahora en la terminal, escribe el siguiente comando.
heroku crear
agrega git
git commit -m «Confirmación inicial»
git push heroku maestro
Paso 10: Aparecerá una URL, que es la URL de su aplicación alojada.
Enlace de la aplicación implementada: https://thawing-ravine-87998.herokuapp.com/
Publicación traducida automáticamente
Artículo escrito por ishanrastogi26 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA