Anuncios

Bienvenidos sean a este post, hoy crearemos una aplicacion mas completa.

Anuncios

En este post no solo repasaremos lo visto anteriormente sino que tambien agregaremos algunos temas mas como son el uso de plantillas para nuestras paginas,, asi como iconos y otros elementos, el manejo de informacion en formularios y otros temas mas. Antes de comenzar con el post vamos a crear la base de nuestra aplicacion, para ello deben crear un nuevo directorio con el nombre de app-node, ingresan al mismo y ejecutan los siguientes comandos:

$ npm init
$ npm install express
$ npm install @types/express --save-dev
$ tsc --init
$ npm install config
$ npm install @types/config --save-dev
Anuncios

El primero creara el archivo json de nuestro proyecto, contesten el cuestionario con los valores predeterminados, el siguiente instala el modulo de express,, el tercero los archivos de declaracion de express para typescript, el cuarto genera el archivo json para typescript y los ultimos dos seran para instalar el modulo de configuraciones y sus archivos de declaraciones que vimos en el post anterior. Lo siguiente que haremos sera crear un nuevo directorio llamado routes, ingresaremos a este y creraremos primero un archivo llamado index.ts y le agregaremos el siguiente codigo:

routes/index.ts

import express from 'express';
let router = express.Router();
router.get('/',
        (
                req: express.Request,
                res: express.Response
        ) => {
                res.render('index',
                        {
                                titulo: 'App de Express',
                                msj: 'Bienvenido a la App.'
                        }
                )
        }
);
export { router };
Anuncios
Anuncios

Esto es similar a lo que vimos en este post, es casi el mismo codigo, donde primero importamos el modulo de express para usar al metodo router mediante un objeto, este tiene el metodo get para obtener la url que usara. En este tenemos dos objetos para la solicitud (Request) y la respuesta (Response). En el post antes citado usabamos a send para enviar un mensaje a la pagina. En cambio, en este usamos a render para que nos dibuje o renderice una vista. La misma sera identificada como index y a su vez le pasamos dos propiedades que son para el titulo y el mensaje en la pagina pero sobre esto hablaremos en un momento. Por ultimo, exportamos a nuetro objeto router para poder redireccionarnos a esta pagina. Nuestro siguiente paso sera volver al directorio raiz de la aplicacion y crear un nuevo directorio con el nombre de config, en este crearemos un archivo con el nombre de default.json y le agregaremos el siguiente codigo:

config/default.json

{
        "puerto": 9999
}
Anuncios

Este representara el puerto que usaremos para acceder a nuestra aplicacion. Lo siguiente sera volver al directorio raiz y crearermos un archivo con el nombre de main.ts. A este le agregaremos el siguiente codigo:

main.ts

import express from 'express';
import config from 'config';
import * as path from 'path';
import * as Indice from './routes/index';

enum OpcConfig {
        PUERTO = 'puerto'
}
let app = express();
let puerto = 3000;
if (config.has(OpcConfig.PUERTO)) {
        puerto = config.get(OpcConfig.PUERTO);
} else {
        console.log(`puerto no encontrado, usando default ${puerto}`);
}

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use('/', Indice.router);


app.listen(puerto,() => {
        console.log(`escuchando en el puerto ${puerto}`);
});
Anuncios
Anuncios

Este sera nuestra aplicacion base, primero importamos a express, despues el modulo encargado de cargar las configuraciones en el json creado anteriormente, tambien importamos un modulo llamado path para poder trabajar con los distintos paths en el PC e importamos al archivo de ruteo para la pagina principal. El enum que definimos es para representar las distintas configuraciones que podemos disponer. En este caso al ser una sola, solamente definimos una constante con el nombre del valor que debemos recuperar. Lo siguiente es crear un objeto y una variable, el primero sera para acceder a todos los metodos de express y la variable sera para establecer un valor de puerto predeterminado en caso de no informar uno en el archivo de configuraciones. El condicional que sigue verifica si el valor de la constante existe en el archivo de configuraciones. En caso de ser verdadero le asigna ese valor a la variable de lo contrarrio nos nuestra un mensaje y usa el valor predeterminado. Despues de esto usaremos al metodo set de Express para establecer el valor de donde sacaremos las vistas de nuestras paginas y mediante path.join estableceremos a donde apunta. El siguiente metodo es para establecer cual sera nuestro engine para crear las vistas.

Anuncios

Luego aplicamos el metodo use para monitorear la barra y lo pasamos al ruteador de nuestra pagina principal y por ultimo, tenemos el listen que sera el encargado de habilitar el puerto para poder conectarnos y nos notifica en la consola cual es el puerto a conectarnos.

Anuncios

El siguiente paso sera crear un nuevo directorio con el nombre de views, este es el que designamos anteriormente para las vistas,, y en el crearemos un nuevo archivo con el nombre de index.hbs y le agregaremos este codigo:

views/index.hbs

<h1>{{{msj}}}</h1>
Anuncios

Esta sera la vista que renderiza nuestro archivo index.ts y mostrara el texto de la propiedad msj. Solo nos resta ejecutar el siguiente comando:

$ npm install hbs
Anuncios

Este comando nos instalara todo lo relacionado al engine que manejara nuestras vistas, Con todo esto realizado podemos ccompilarlo mediante el comando tsc y ejecutarlo con node main, si todo sale bien se quedara escuchando en el puerto 9999 y veremos lo siguiente si lo abrimos desde un browser:

Anuncios

Aqui tenemos solamente el mensaje del cuerpo pero y el titulo? Aqui tenemos dos opciones, lo agregamos como el mensaje o vamos al directorio views y creamos un archivo con el nombre de layout.hbs y le agregamos el siguiente codigo:

views/layout.hbs

<!DOCTYPE html>
<html>
<head>
        <title>{{titulo}}</title>
        <link
                rel="stylesheet"
                type="text/css"
                href="/css/bootstrap.min.css" />
</head>
<body>
        {{{body}}}
</body>
</html>
Anuncios
Anuncios

Como pueden ver es una estructura basica de una pagina HTML donde tenemos cada una de sus partes, en el head tenemos el titulo y le pasamos la propiedad titulo que usamos en index.ts. Tambien agregamos un link para que cargue un archivo css, que aun no existe, y en el body agregamos una opcion body pero a diferencia de titulo en lugar de usar dos llaves le pusimos tres, esto es para que podamos inyectarle cualquier otro layout. Si lo prueban nuevamente la unica diferencia que veran es que ahora la pagina si tiene un titulo. Esto es gracias a que este es el archivo predeterminado para establecer como vista y podamos alternarla con distintos contenidos. Pero esto lo vamos a mejorar con un par de cosas, la primera sera ejecutar el siguiente comando desde la raiz del directorio de nuestra aplicacion:

$ npm install bootstrap
Anuncios

Esto nos instalara todos los elementos del bootstrap para que podamos aplicarlo a nuestras vistas. Ahora crearemos un nuevo directorio con el nombre de resources y dentro de este otro directorio con el nombre de css. Una vez creado debemos ejecutar el siguiente comando desde el directorio raiz:

$ cp node_modules/bootstrap/dist/css/bootstrap.min.css resources/css/
Anuncios

Esto nos copiara el archivo css que llamamos en el layout. Desde node_modules al nuevo recurso que creamos. La siguiente modificacion la haremos en main.ts donde antes del llamado al listen agregaremos la siguiente linea:

app.use(express.static(path.join(__dirname, 'resources')));
Anuncios

Esta linea genera un recurso estatico, es decir ahora el recurso que llamamos en layout.hbs lo buscara directamente sin necesidad de configurar nada mas. Por lo tanto, todo recurso que necesitemos agregar lo haremos directamente en el directorio resources con el path que necesitemos. Si lo prueban veran que se modifico la estetica de nuestra pagina. Pasemos a realizar algo mas interesante y para ello debemos ir primero a nuestro directorio views y crearemos un nuevo archivo con el nombre de login.hbs y le agregaremos el siguiente codigo:

views/login.hbs

<h1>Ingreso</h1>
<form method="post">
        <p>{{mensajeError}}</p>
        <p>Usuario:
                <input type="text" name="usuario" />
        </p>
        <p>Clave:
                <input type="password" name="clave" />
        </p>
        <button type="submit" class="btn btn-primary!>
        Ingreso
        </button>
</form>
Anuncios

Aqui tenemos un form que utiliza el metodo post para enviar los datos que contenga. Dentro contendra tres elementos, uno de ingreso de texto, otro de password y un button para ejecutar el form. Los input tienen sus identificadores y el button es de tipo submit. Tambien tenemos un mensaje de error en caso de que alguno de los de los datos sea incorrecto. Nuestro siguiente paso sera crear un archivo en routes con el nombre de login.ts y le agregaremos el siguiente codigo:

routes/login.ts

import express from 'express';
let router = express.Router();

router.get('/login',
        (
                req: express.Request,
                res: express.Response
        ) => {
                res.render('login', {
                        titulo: 'Ingreso a la App'
                });
        }
);

router.post('/login',
        (
                req: express.Request,
                res: express.Response,
                next: express.NextFunction
        ) => {
                console.log(`usuario: ${req.body.usuario}`);
        }
);

export { router };
Anuncios
Anuncios

Primero importaremos a express y luego en un objeto almacenaremos al metodo Router para trabajar con el. Nuestro primer uso sera con get y sera para cuando «ruteemos» para la pagina. En esta tendremos dos objetos para recibir las solicitud (Request) y enviar la respuesta (Response). En la funcion al igual que en index.ts volveremos a usar render para mostrar la vista login y le pasaremos una sola propiedad llamada titulo. Luego volvemos a usar el objeto router pero ahora con el metodo post. Este sera el encargado de capturar los datos enviados por el form, tendra los mismos objetos que el anterior pero tambien otro nuevo pero en esta ocasion no lo usaremos para nuestra aplicacion. Porque este es utilizado para cuando necesitamos trabajar con funciones de callback. Volviendo a la funcion, esta nos mostrara el usuario en pantalla cuando sea enviado. Nuestro siguiente paso sera ejecutar el siguiente comando:

$ npm install body-parser
Anuncios

Este nos instalara un modulo que sera el verdadero encargado de enviar los datos de los formularios para que podemos manejarlos. El proximo paso sera modificar a main.ts de la siguiente manera:

import express from 'express';
import config from 'config';
import * as path from 'path';
import * as Indice from './routes/index';
import * as Login from './routes/login';
import bodyParser from 'body-parser';

enum OpcConfig {
        PUERTO = 'puerto'
}
let app = express();
let puerto = 3000;
if (config.has(OpcConfig.PUERTO)) {
        puerto = config.get(OpcConfig.PUERTO);
} else {
        console.log(`puerto no encontrado, usando default ${puerto}`);
}

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.use('/', Indice.router);
app.use('/', Login.router);
app.use(express.static(path.join(__dirname, 'resources')));

app.listen(puerto,() => {
        console.log(`escuchando en el puerto ${puerto}`);
});
Anuncios

En este caso, solo agregamos la importacion del router desde el archivo de login, asi como tambien al modulo de body-parser. La siguiente modificacion es el agregado del llamado al metodo json para manejar la informacion y luego la forma de como manejaremos a la misma. Por ultimo, agregamos un nuevo ruteo para direccionar al archivo de login. Si lo compilamos y ejecutamos veremos lo siguiente si nos dirijimos a la pagina de login.

Anuncios

Y si presionan el boton de ingreso, en la consola veran lo siguiente

$ node main
escuchando en el puerto 9999
usuario: tinchicus
Anuncios

Como pueden ver recibimos el valor ingresado en el elemento input del usuario. Pero esto es solo la mitad de todo, pasemos al siguiente nivel.

Anuncios

Express tiene muchas cosas muy buenas pero una de las mas interesantes es la capacidad de poder crear sesiones y poder establecer cuando un usuario ingreso o no. Es decir, almacena en una variable de sesion al usuario para poder permitirle tener accceso. Para esto debemos ejecutar el sigueinte comando:

$ npm install express-session
Anuncios

Esto nos instalara el modulo para manejar las sesiones y ahora corramos el siguiente comando:

$ npm install @types/express-session --save-dev
Anuncios

Este nos instalara los archivos de declaracion para typescript. Ya tenemos los modulos para poder trabajar, ahora comencemos con la modificacion de los distintos archivos. Nuestro siguiente paso sera ir a login.ts en el directorio routes y lo modificaremos de la siguiente manera:

import express from 'express';
import { IDataSesion } from './DataSesion';

let router = express.Router();

router.get('/login',
        (
                req: express.Request,
                res: express.Response
        ) => {
                res.render('login', {
                        titulo: 'Ingreso a la App'
                });
        }
);

router.post('/login',
        (
                req: express.Request,
                res: express.Response,
                next: express.NextFunction
        ) => {
                console.log(`usuario: ${req.body.usuario}`);
                if (req.body.usuario?.length > 0) {
                  console.log('usuario encontrado');
                  (<IDataSesion>req.session).usuario = req.body.usuario;
                  res.redirect('/');
                } else {
                  res.render('login', {
                        titulo: 'Ingreso a la App',
                        mensajeError: 'Usuario o clave incorrecta'
                  })
                }
        }
);

export { router };
Anuncios
Anuncios

El primer cambio es la importacion de una interfaz que sera los datos de la sesion, pero de eso hablaremos en un momento, la siguiente modificacion es en el metodo post. Donde despues de mostrar el valor recibido agregamos un condicional donde verifica si el tamaño del valor recibido es mayor a cero. En caso de ser verdadero notifica que se encontro el usuario en la consola y estableceremos la sesion, previamente haremos un casteo del tipo de la interfaz, y le establecemos el valor recibido para finalmente redireccionarlo a la pagina de inicio. En caso contrario nos renderiza al login, le pasamos el titulo nuevamente pero ahora establecemos el mensaje de error y lo mostrara. En el directorio de routes vamos a crear otro archivo con el nombre de DataSesion.ts y le agregaremos el siguiente codigo:

routes/DataSesion.ts

import session from 'express-session';
export interface IDataSesion extends session.Session {
        usuario: string;
}
Anuncios

En este simplemente importamos a session del modulo express-session y luego creamos una interfaz que la extiende y que sera el tipo de dato que utilizamos anteriormente, en este solo almacenamos un dato que sera el usuario en cuestion. La siguiente modificacion la haremos en index.ts dentro del mismo directorio, para ello iremos a ese archivo y lo modificaremos de la siguiente manera:

import express from 'express';
import { IDataSesion } from './DataSesion';

let router = express.Router();
router.get('/',
        (
                req: express.Request,
                res: express.Response
        ) => {
                res.render('index',
                        {
                          titulo: 'App de Express',
                          msj: 'Bienvenido a la App.',
                          usuario: (<IDataSesion>req.session).usuario
                        }
                )
        }
);
export { router };
Anuncios

Aqui volvemos a importar a la interfaz que creamos anteriormente y luego la usamos como nueva propiedad para el renderizado de la pagina principal. Volvemos a hacer un casteo sobre la sesion de la solicitud y le especificamos la propiedad a asignarle. La siguiente modificacion es index.hbs del directorio views donde modificaremos el codigo de la siguiente manera:

<h1>{{{msj}}}</h1>
{{#if usuario}}
<p>Usuario: {{usuario}} ingresado.</p>
{{else}}
<p>Click <a href='/login'>aqui</a> para ingresar</p>
{{/if}}
Anuncios

Aqui agregamos una caracteristica que me gusta mucho de node, como es la capacidad de poder agregar elementos de una manera sencilla. Aqui tenemos un condicional donde si el valor de usuario esta ingresado nos muestra cual es de lo contrario nos muestra un mensaje para ingresar y nos permite ir a la pagina de ingreso. Solo nos falta la parte que controla la sesion en el main y para ello debemos ir a main.ts y lo modificaremos de la siguiente manera:

import express from 'express';
import config from 'config';
import * as path from 'path';
import * as Indice from './routes/index';
import * as Login from './routes/login';
import bodyParser from 'body-parser';
import expressSession from 'express-session';

enum OpcConfig {
        PUERTO = 'puerto'
}
let app = express();
let puerto = 3000;
if (config.has(OpcConfig.PUERTO)) {
        puerto = config.get(OpcConfig.PUERTO);
} else {
        console.log(`puerto no encontrado, usando default ${puerto}`);
}

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(expressSession(
        {
                secret: 'teclado',
                resave: false,
                saveUninitialized: true
        }
));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));
app.use('/', Indice.router);
app.use('/', Login.router);
app.use(express.static(path.join(__dirname, 'resources')));

app.listen(puerto,() => {
        console.log(`escuchando en el puerto ${puerto}`);
});
Anuncios

Primero importaremos a expressSession del modulo para poder manipular las sesiones. La siguiente modificacion es mediante use donde la iniciaremos y pasaremos tres valores. La primera es una palabra que se usara para intercambiar y puede ser cualquiera o una combinacion, la siguiente es para decirle que no la grabe y la ultima es para que siempre inicie en blanco. En este caso lo hacemos asi por un tema de practicidad. Con esto ya podemos pasar a probar como funciona, para ello compilen mediante el comando tsc y ejecuten el comando node main, la aplicacion se quedara escuchando y podemos acceder mediante el browser. Veamos como trabaja mediante el siguiente video

Anuncios

En el video podemos ver como trabaja nuestra pagina ahora, donde nos permite ingresar a la pagina de ingreso o login. A su vez, vemos que sucede cuando no se ingresa un usuario y cuando lo hacemos. Antes de finalizar les dejo un link con todos los archivos del proyecto:

Anuncios

Y si sienten curiosidad por saber mas sobre node, les dejo un post con todos los posts subidos en este blog donde hablo sobre este engine y su framework Express:

Anuncios

En resumen, hoy hemos visto una aplicacion de node, como se genera desde cero, con todas las herramientas necesarias para generarla mediante typescript, hemos incorporado lo visto anteriormente, asi como tambien nuevas herrramientas que nos brinda Express. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Donatión

It’s for site maintenance, thanks!

$1.50