En este tutorial vamos a ver cómo crear un sencillo proyecto con nodejs utilizando express 4 unido a angularjs, es decir, una aplicación con nodejs y angularjs utilizando express en su versión 4.
Veremos cómo crear el proyecto y modificar el motor de plantillas para utilizar ejs, si tienes dudas, aquí tienes un vídeo tutorial donde explicamos brevemente ejs.
Añadiremos angular, angular-route y bootstrap haciendo uso de bower.
Crearemos la configuración básica con angularjs para poder trabajar con la directiva ng-view, es decir, haremos la configuración de nuestras rutas con el objeto $routeProvider
de angularjs.
Finalmente, para este tutorial, nuestra misión será ejecutar un formulario de login desde angularjs y recibirlo con nodejs a través del objeto req.body de nodejs, para ello crearemos un servicio con angularjs haciendo uso del objeto $http el cuál nos sirve para ejecutar peticiones get, post, put y delete, ideales para trabajar con nodejs.
Crear un proyecto con NodeJS y Express
Para crear nuestro proyecto con nodejs y express ejecute el siguiente comando desde la terminal.
1 2 |
express nodeangular && cd nodeangular npm install |
Cómo ya hemos dicho, vamos a instalar ejs, para ello ejecuta el siguiente comando.
1 |
npm install ejs --save |
Ahora ya tenemos instalado nodejs con express y ejs, ahora vamos.
Instalar AngularJS con Bower
Para instalar angularjs con bower colócate en el directorio public del proyecto y ejecuta las siguientes líneas en la terminal.
1 2 3 |
bower install angular bower install angular-route bower install bootstrap |
Simplemente instalamos angular, angular-route para utilizar las rutas de angularjs y bootstrap para la maquetación.
Los comandos anteriores debes ejecutarlos uno por uno, una vez hecho, se habrá creado una carpeta llamada bower_components dentro de public, la cuál contiene todo lo necesario.
Configurar la aplicación en Express
Ahora abre el archivo app.js de la raíz del proyecto, el cuál contiene todo lo necesario para que nodejs corra junto con express y reemplaza el código por el siguiente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
var express = require('express'); var path = require('path'); var favicon = require('static-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var routes = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.engine("html", require("ejs").renderFile); app.set('view engine', 'html'); app.use(favicon()); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded()); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); app.use('/users', users); /// catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); /// error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); module.exports = app; |
Lo único que hemos modificado han sido las siguientes líneas.
1 2 |
app.engine("html", require("ejs").renderFile); app.set('view engine', 'html'); |
De esta forma hemos cambiado el motor de plantillas jade por ejs.
Ahora cambia la extensión a los archivos alojados en el directorio views por .html y vamos paso a paso, abre el archivo error.html y reemplaza el código por el siguiente.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!DOCTYPE html> <html> <head> <title></title> </head> <body> <h1><%=message%></h1> <h2><%=error.status%></h2> <div><%=error.stack%></div> </body> </html> |
Haz lo mismo con el archivo index.html.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html> <html ng-app="app"> <head> <title><%= title %></title> <link rel="stylesheet" type="text/css" href="bower_components/bootstrap/dist/css/bootstrap.min.css"> <script src="bower_components/angular/angular.min.js"></script> <script src="bower_components/angular-route/angular-route.min.js"></script> <script src="javascripts/app.js"></script> </head> <body ng-controller="homeCtrl"> <div class="container"> <div ng-view></div> </div> </body> </html> |
Aquí cargamos los archivos que vamos a necesitar en nuestro proyecto, una vez hecho, cargamos la app con la directiva ng-app y decimos que todas nuestras vistas se rendericen a través de la directiva ng-view, el objeto $routeProvider será el encargado de ofrecer esa configuración, para ello tenemos que crear un archivo app.js dentro del directorio public/javascripts y añadir el siguiente código.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
var app = angular.module("app", ["ngRoute"]); app.config(function($routeProvider) { $routeProvider.when("/", { templateUrl : "templates/home.html", controller : "homeCtrl" }) .when("/login", { templateUrl : "templates/login.html", controller : "loginCtrl" }) .when("/profile", { templateUrl: "templates/profile.html", controller: "profileCtrl" }) .otherwise({ redirectTo : "/" }); }) app.controller('homeCtrl', ['$scope', function($scope) { $scope.saludo = "Hola desde la home"; }]); app.controller('loginCtrl', ['$scope', 'loginService', function($scope, loginService) { $scope.saludo = "Hola desde login"; $scope.login = function(user) { loginService.login('email='+user.email+'&password='+user.password).then(function(result) { alert(JSON.stringify(result)); }); } }]); app.controller('profileCtrl', ['$scope', function($scope) { $scope.saludo = "Hola desde profile"; }]); app.service('loginService', ['$http', function($http) { var obj = {}; $http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; obj.login = function(user) { return $http.post('/login', user).then(function(results) { return results; }); } return obj; }]); |
Si tienes dudas sobre algo en lo que respecta a AngularJS tienes más de 40 entradas en el blog y un curso completo de angularjs donde aprenderás todo lo que necesitas para empezar a crear aplicaciones de este tipo.
Si nos fijamos, hemos creado la configuración de las rutas con el objeto $routeProvider, a continuación creamos los controladores home, login y profile con la coletilla Ctrl, es un standard del desarrollo en angularjs.
Creamos un servicio llamado loginService al cuál le pasamos el objeto $http para poder hacer la petición post y así enviar nuestro formulario de login.
Ahora abre el archivo routes/index.js y añade el siguiente código.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res) { res.render('index', { title: 'Express', framework: 'AngularJS'}); }); router.post('/login', function(req, res) { res.send(req.body); }) module.exports = router; |
Lo único que hemos añadido es la ruta post contra login, y simplemente devolvemos con res.send los datos llegados vía post a través de req.body.
Ahora crea una carpeta nueva en public llamada templates y crea tres archivos, home.html, login.html y profile.html, abre el primero y añade el siguiente código.
1 2 3 4 |
<div class="row"> <p>{{saludo}}</p> <a class="btn btn-primary col-md-12" ng-href="#login">Go login</a> </div> |
Ahora abre el archivo login.html y haz lo mismo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<!--http://bootsnipp.com/snippets/featured/compact-login-form-bs-3--> <div class="row"> <div class="col-md-4 col-md-offset-4"> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">Please sign in</h3> </div> <div class="panel-body"> <form accept-charset="UTF-8" role="form"> <fieldset> <div class="form-group"> <input class="form-control" placeholder="E-mail" ng-model="user.email" type="text"> </div> <div class="form-group"> <input class="form-control" placeholder="Password" ng-model="user.password" type="password"> </div> <div class="checkbox"> <label> <input name="remember" type="checkbox" value="Remember Me"> Remember Me </label> </div> <input class="btn btn-lg btn-success btn-block" type="button" ng-click="login(user)" value="Login"> </fieldset> </form> </div> </div> </div> </div> |
Finalmente haz lo mismo con el archivo profile.html.
1 2 3 4 |
<div class="row"> <p>{{saludo}}</p> <a class="btn btn-primary col-md-12" ng-href="#">Go home</a> </div> |
Ahora sólo debes ejecutar tu aplicación con el siguiente comando y abrir la url http://localhost:3000 en tu navegador.
1 |
npm start |
Si todo ha ido bien, tu aplicación debe funcionar de forma completa, tanto las rutas como el formulario de login, que te debe devolver un alert con un json en formato string donde podrás ver toda la información de la petición post que hemos hecho.
Eso es todo por este tutorial, espero que te haya gustado y cualquier duda no dudes en comentar, saludos.