<div id="contentMain">
<div>
<center>
<img src="http://res.cloudinary.com/dzemqknqv/image/upload/v1612793376/in2qlclbuvqgnknu7pdk.jpg" class="img-fluid" />
</center><br/>
</div>
<p>En el día de hoy te ensenare a como conectar una base de datos mysql https://www.npmjs.com/package/mysql2 con Nodejs para crear un sistema de carga, listado, actualizado y eliminado de tareas muy simple, usaremos el motor de plantillas handlebars donde aprenderemos a configurarlo también </p>
<p>Empezaremos creando una carpeta en nuestro escritorio <code>/to-do-node-mysql</code> y activando la consola de nuestro editor de código favorito, e instalaremos las siguientes dependencias: </p>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code"><b class="token function">npm</b> init --yes
</code>
</pre>
</div>
<br/>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code"><b class="token function">npm</b> i express mysql2 express-handlebars
</code>
</pre>
</div>
<br/>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code"><b class="token function">npm</b> i --save-dev @babel/node @babel/core @babel/cli @babel/preset-env nodemon
</code>
</pre>
</div>
<p>Creamos un archivo llamado <code>.babelrc</code> con lo siguiente:</p>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code">{
"presets" : [
"@babel/env"
]
}
</code>
</pre>
</div>
<p>configuramos el archivo <code>package.json</code> con lo siguiente:</p>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code">"dev": "nodemon src/index.js --exec babel-node",
"build":"babel src --out-dir build",
"start": "node build/index.js"
</code>
</pre>
</div>
<p>A continuación crearemos la estructura del proyecto:</p>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code">dentro de la carpeta <b>src/</b> crearemos esta estructura
views/
routes/
index.js
server.js
database.js
</code>
</pre>
</div>
<p>Para este ejemplo descargaremos <code>xamp</code> y lo ejecutarermos y activaremos <code>apache</code> y <code>mysql</code></p>
<div>
<center>
<img src="http://res.cloudinary.com/dzemqknqv/image/upload/v1612792741/vfvz9gpfdrid8auopzm8.jpg" class="img-fluid" />
</center><br/>
</div>
<p>Ahora vamos al navegador y escribimos localhost/phpmyadmin y procedemos a crear una base de datos</p>
<div>
<center>
<img src="http://res.cloudinary.com/dzemqknqv/image/upload/v1612792809/gqybhhyqgljtyrespist.jpg" class="img-fluid" />
</center><br/>
</div>
<p>Creamos una tabla llamada <code>tasks</code> con 3 campos {id, task, created_at}</p>
<div>
<center>
<img src="http://res.cloudinary.com/dzemqknqv/image/upload/v1612792820/eb3cj00icg880tqcnmm3.jpg" class="img-fluid" />
</center><br/>
</div>
<div>
<center>
<img src="http://res.cloudinary.com/dzemqknqv/image/upload/v1612792834/c0zhmwrfehj7cpujdobl.jpg" class="img-fluid" />
</center><br/>
</div>
<p>Procedemos a crear algunos registros</p>
<div>
<center>
<img src="http://res.cloudinary.com/dzemqknqv/image/upload/v1612793210/uwes97qifjtxha9agafe.jpg" class="img-fluid" />
</center><br/>
</div>
<p>Configuraremos nuestro servidor y el motor de plantillas (handlebars) y algunos middlewares</p>
<div><b>index.js</b></div>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code">import app from './server'
app.listen(4000, () => console.log('Server on port 4000'))
</code>
</pre>
</div>
<div><b>server.js</b></div>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code">import express from 'express'
import routes from './routes/'
import exphbs from 'express-handlebars'
import path from 'path'
const app = express()
app.set('views', path.join(__dirname,'views'))
app.engine('.hbs', exphbs({
defaultLayout:'main',
layoutsDir: path.join(app.get('views'),'layouts'),
partialsDir: path.join(app.get('views'),'partials'),
extname:'.hbs'
}))
app.set('view engine','.hbs')
// Middlewares
app.use(express.json())
app.use(express.urlencoded({extended:false}))
app.use(routes)
app.use(express.static(path.join(__dirname,'public')))
export default app
</code>
</pre>
</div>
<p>Ahora vamos a configurar nuestra conexión con mysql</p>
<div><b>database.js</b></div>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code">import mysql from 'mysql2/promise'
export default async function conn() {
const pool = await mysql.createConnection({
host:'localhost',
user:'root',
database:'to_do_node_mysql'
})
return pool;
}
</code>
</pre>
</div>
<p>Creamos una ruta para probar nuestra conexión con la base de datos</p>
<div><b>routes/index.js</b></div>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code">import {Router} from 'express'
import conn from '../database'
const router = Router()
router.get('/', async (req, res) => {
try{
const pool = await conn()
const [results] = await pool.query('SELECT * FROM tasks')
pool.end()
res.render('home', {results})
}
catch(e){ console.log(e)}
})
export default router
</code>
</pre>
</div>
<p>Procedemos a crear las vistas y estilizar nuestra app </p>
<div><b>view/layouts/main.hbs</b></div>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code"><!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>Tutorial - Aprende a crear una lista de tareas con Mysql y Node</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
{{{body}}}
</body>
</html>
</code>
</pre>
</div>
<div><b>view/home.hbs</b></div>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code"><div>
<h1>Tutorial - Aprende a crear una lista de tareas con Node y Mysql <code>Jfdesousa7</code></h1>
<ul>
{{#each results}}
<li>{{task}}</li>
{{/each}}
</ul>
</div>
</code>
</pre>
</div>
<div>
<center>
<img src="http://res.cloudinary.com/dzemqknqv/image/upload/v1612793309/zy9tmtfrrnizimhrzknn.jpg" class="img-fluid" />
</center><br/>
</div>
<p>Procedemos a crear nuestro formulario para la carga de tareas</p>
<div><b>view/home.hbs</b></div>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code"><div id="wrapper">
<h1>Tutorial - Aprende a crear una lista de tareas con Node y Mysql <code>Jfdesousa7</code></h1>
<div class="container">
<div>
<ul>
{{#each results}}
<li>{{task}}</li>
{{/each}}
</ul>
</div>
<div>
<form action="" method="POST">
<div class="form-group">
<label for="task">Taks</label>
<input type="text" required id="task" name="task" placeholder="Introduce task" autofocus>
</div>
<div class="form-group">
<button>Save task</button>
</div>
</form>
</div>
</div>
</div>
</code>
</pre>
</div>
<div>
<center>
<img src="http://res.cloudinary.com/dzemqknqv/image/upload/v1612793340/y4qz8wwrvdglkk9kt0yz.jpg" class="img-fluid" />
</center><br/>
</div>
<p>Crearemos el resto de las rutas y su funcionamiento</p>
<div><b>routes/index.js</b></div>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code">import {Router} from 'express'
import conn from '../database'
const router = Router()
router.get('/', async (req, res) => {
try{
const pool = await conn()
const [results] = await pool.query('SELECT * FROM tasks')
pool.end()
res.render('home', {results})
}
catch(e){ console.log(e)}
})
router.post('/', async (req, res) => {
const {task} = req.body
try{
const pool = await conn()
await pool.query('insert into tasks(task) values(?)',[task])
pool.end()
res.redirect('/')
}
catch(e){ console.log(e)}
})
router.get('/task/edit/:id', async (req, res) => {
const {id} = req.params
try{
const pool = await conn()
const [results] = await pool.query('select * from tasks where id=?',[id])
pool.end()
res.render('editTask', {task:results[0]})
}
catch(e){ console.log(e)}
})
router.post('/task/edit/:id', async (req, res) => {
const {id} = req.params
const {task} = req.body
try{
const pool = await conn()
await pool.query('update tasks set task=? where id=?',[task,id])
pool.end()
res.redirect('/')
}
catch(e){ console.log(e)}
})
router.get('/delete/:id', async (req, res) => {
const {id} = req.params
try{
const pool = await conn()
const [results] = await pool.query('delete from tasks where id = ?',[id])
pool.end()
res.redirect('/')
}
catch(e){ console.log(e)}
})
export default router
</code>
</pre>
</div>
<p>Crearemos la última vista que es la editar tarea</p>
<div><b>views/editTask.hbs</b></div>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code"><div id="wrapper">
<h1>Tutorial - Aprende a crear una lista de tareas con Node y Mysql <code>Edit task</code></h1>
<div class="container">
<div>
<form action="/task/edit/{{task.id}}" method="POST">
<div class="form-group">
<label for="task">Taks</label>
<input type="text" required id="task" name="task" placeholder="Introduce task" autofocus value="{{task.task}}" >
</div>
<div class="form-group">
<button>Edit task</button>
</div>
</form>
</div>
</div>
</div>
</code>
</pre>
</div>
<p>Por ultimo el estilo creado para este ejemplo dentro de la carpeta public/styles.css</p>
<div><b>public/styles.css</b></div>
<div class="gatsby-highlight">
<pre class="gatsby-code">
<code class="gatsby-code">@import url('https://fonts.googleapis.com/css2?family=Anaheim&display=swap');
*,
*::before,
*::after {
box-sizing: border-box;
margin:0;
padding:0
}
body{
font-family: 'Anaheim', sans-serif;
font-weight:700;
color:#222
}
div {padding:2em}
ul{padding:2em}
ul li {
text-transform: uppercase;
padding:.5em;
display:flex
}
ul li a {
padding-left: 1em;
}
ul li a i{
padding-top:0;
font-size:.7em;
}
ul li a:last-child{
color:red
}
code {
color: red;
font-size:.7em
}
.container {
display: grid;
grid-template-columns : 50% 50%;
grid-gap:1em;
}
#wrapper .container > div:last-child {
background-color: #f8f8f8;
justify-self: center;
}
input[type=text]{
padding:1em;
}
button {
padding:1em;
background-color:aqua;
border:0;
font-weight:bold;
width:100%
}
@media only screen and (max-width: 540px) {
.container {
grid-template-columns : 100%;
}
}
</code>
</pre>
</div>
<p><h2>Adjunto fotos del ejemplo en su fase final</h2></p>
<div>
<center>
<img src="http://res.cloudinary.com/dzemqknqv/image/upload/v1612793351/v2jcvrgjgxihxiv7cb9e.jpg" class="img-fluid" />
</center><br/>
</div>
<div>
<center>
<img src="http://res.cloudinary.com/dzemqknqv/image/upload/v1612793359/pznbrkfpg9obntkns1n8.jpg" class="img-fluid" />
</center><br/>
</div>
<br/><br/><br/><br/><br/>
<p>Y con esa amigos llegamos al final del tutorial, espero que lo hayan disfrutado y hasta la próxima! </p><br/>
<p style="color:red">Visita mi sitio web oficial</p>
<center><a href="https://tupaginaonline.net" target="_blank"><b>tupaginaonline.net</b></a></center>
</div>