Advertisement
  1. Code
  2. Angular

Crea una aplicación AngularJS desde cero, con la tecnología de Python EVE

Scroll to top
Read Time: 12 min

() translation by (you can also view the original English article)

En la parte anterior de esta serie, vimos cómo comenzar con Eve, un framework API REST de Python, y cómo crear algunas API. En esta parte de la serie, usaremos esas API para crear una aplicación impulsada por Node.js y AngularJS.

Implementaremos la funcionalidad de registro usando Node.js y agregaremos otras funcionalidades llamando a las API REST desde AngularJS.

Empecemos

Para comenzar, clona el código fuente del tutorial anterior y ejecuta las API.

1
git clone https://github.com/jay3dec/REST_API_EVE_Part-1

Una vez que hayas clonado el código fuente, asegúrate de tener MongoDB en ejecución. Navega hasta el directorio REST_API_EVE_Part-1 y ejecuta la aplicación:

1
cd REST_API_EVE_Part-1
2
python app.py

Ahora, deberías tener tu API ejecutándose en http://localhost:5000/.

Creando la aplicación NodeJS

Paso 1: Creando una aplicación básica

Crea una carpeta de proyecto llamada AngularNodeApp. Usaremos Express, un framework de aplicación web minimalista para crear aplicaciones Node.js. Por lo tanto, vamos a instalar express en nuestro proyecto.

1
npm install express

Una vez que se haya instalado express, crea un archivo llamado app.js. Dentro de app.js crearemos nuestra aplicación de express y definiremos las rutas para la aplicación.

Comencemos por importar express dentro de app.js y crear una aplicación express.

1
var express = require('express'),
2
    app = express();
3
4
app.get('/',function(req,res){
5
    res.send('welcome !!');
6
});
7
8
app.listen(3000)

Acabamos de crear una aplicación express y definimos una ruta, /, que retornará welcome cuando se solicite. Ahora inicia el servidor.

1
node app.js

Apunta tu navegador a http://localhost:3000/ y deberías tener el mensaje welcome !!.

Creemos una página de inicio para nuestra aplicación. Navega a la carpeta del proyecto y crea un nuevo directorio llamado public. Dentro de public/index, crea un archivo llamado index.html. Agrega el siguiente código HTML a index.html.

1
<!DOCTYPE html>
2
<html lang="en">
3
4
<head>
5
    <title>Angular Node App</title>
6
7
8
    <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
9
10
    <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
11
12
13
</head>
14
15
<body>
16
17
    <div class="container">
18
        <div class="header">
19
            <nav>
20
                <ul class="nav nav-pills pull-right">
21
                    <li role="presentation" class="active"><a href="#">Home</a>
22
                    </li>
23
                    <li role="presentation"><a href="/signIn">Sign In</a>
24
                    </li>
25
                    <li role="presentation"><a href="/signUp">Sign Up</a>
26
                    </li>
27
                </ul>
28
            </nav>
29
            <h3 class="text-muted">Angular Node App</h3>
30
        </div>
31
32
        <div class="jumbotron">
33
            <h1>Angular Node App</h1>
34
            <p class="lead"></p>
35
            <p><a class="btn btn-lg btn-success" href="/signUp" role="button">Sign up today</a>
36
            </p>
37
        </div>
38
39
40
41
        <footer class="footer">
42
            <p>&copy; Company 2015</p>
43
        </footer>
44
45
    </div>
46
</body>
47
48
</html>

A continuación, modifiquemos el controlador de solicitudes / existente para mostrar index.html. Define la ruta a la carpeta public en app.js.

1
app.use(express.static(__dirname + '/public'));

Modifica el controlador de solicitudes por / como se muestra a continuación:

1
app.get('/',function(req,res){
2
    res.sendFile('index.html',{'root': __dirname + '/public/index'});
3
});

Guarda los cambios y reinicia el servidor. Apunta tu navegador a http://localhost:3000/ y deberías poder ver la página de la aplicación.

Home PageHome PageHome Page

Ahora, crea una página llamada signin/signin.html y agrega el siguiente código HTML:

1
<!DOCTYPE html>
2
<html lang="en">
3
4
<head>
5
    <title>Python Flask Bucket List App</title>
6
7
8
    <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
9
10
    <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
11
    <link href="signup.css" rel="stylesheet">
12
13
14
</head>
15
16
<body>
17
18
    <div class="container">
19
        <div class="header">
20
            <nav>
21
                <ul class="nav nav-pills pull-right">
22
                    <li role="presentation"><a href="/">Home</a>
23
                    </li>
24
                    <li role="presentation" class="active"><a href="#">Sign In</a>
25
                    </li>
26
                    <li role="presentation"><a href="/signUp">Sign Up</a>
27
                    </li>
28
                </ul>
29
            </nav>
30
            <h3 class="text-muted">Python Flask App</h3>
31
        </div>
32
33
        <div class="jumbotron">
34
            <h1>Bucket List App</h1>
35
            <form class="form-signin">
36
                <label for="inputEmail" class="sr-only">Email address</label>
37
                <input type="email" name="inputEmail" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
38
                <label for="inputPassword" class="sr-only">Password</label>
39
                <input type="password" name="inputPassword" id="inputPassword" class="form-control" placeholder="Password" required>
40
41
                <button id="btnSignIn" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
42
            </form>
43
        </div>
44
45
46
47
        <footer class="footer">
48
            <p>&copy; Company 2015</p>
49
        </footer>
50
51
    </div>
52
</body>
53
54
</html>

En app.js, agrega un controlador de solicitudes llamado /SignIn que mostrará la página signin.html.

1
app.get('/signIn', function(req, res) {
2
    res.sendFile('signin.html', {
3
        'root': __dirname + '/public/signin'
4
    });
5
});

De manera similar, agrega signup.html a la carpeta public/signup con el siguiente código HTML:

1
<!DOCTYPE html>
2
<html lang="en">
3
4
<head>
5
    <title>Python Flask Bucket List App</title>
6
7
8
    <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
9
10
    <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
11
    <link href="signup.css" rel="stylesheet">
12
13
14
</head>
15
16
<body>
17
18
    <div class="container">
19
        <div class="header">
20
            <nav>
21
                <ul class="nav nav-pills pull-right">
22
                    <li role="presentation"><a href="/">Home</a>
23
                    </li>
24
                    <li role="presentation"><a href="/signIn">Sign In</a>
25
                    </li>
26
                    <li role="presentation" class="active"><a href="#">Sign Up</a>
27
                    </li>
28
                </ul>
29
            </nav>
30
            <h3 class="text-muted">Python Flask App</h3>
31
        </div>
32
33
        <div class="jumbotron">
34
            <h1>Bucket List App</h1>
35
            <form class="form-signin" action="/register" method="post">
36
                <label for="inputFirstName" class="sr-only">First Name</label>
37
                <input type="name" name="inputFirstName" id="inputFirstName" class="form-control" placeholder="First Name" required autofocus>
38
                <label for="inputLastName" class="sr-only">Last Name</label>
39
                <input type="name" name="inputLastName" id="inputLastName" class="form-control" placeholder="Last Name" required autofocus>
40
                <label for="inputUsername" class="sr-only">Username</label>
41
                <input type="name" name="inputUsername" id="inputUsername" class="form-control" placeholder="Username" required autofocus>
42
                <label for="inputPassword" class="sr-only">Password</label>
43
                <input type="password" name="inputPassword" id="inputPassword" class="form-control" placeholder="Password" required>
44
                <label for="inputPhone" class="sr-only">Password</label>
45
                <input type="number" name="inputPhone" id="inputPhone" class="form-control" placeholder="Phone" required>
46
47
                <button id="btnSignUp" class="btn btn-lg btn-primary btn-block" type="submit">Sign up</button>
48
            </form>
49
        </div>
50
51
52
53
        <footer class="footer">
54
            <p>&copy; Company 2015</p>
55
        </footer>
56
57
    </div>
58
</body>
59
60
</html>

Agrega un controlador de solicitudes llamado signUp en app.js.

1
app.get('/signUp', function(req, res) {
2
    res.sendFile('signup.html', {
3
        'root': __dirname + '/public/signup'
4
    });
5
});

Guarda los cambios y reinicia el servidor. Apunta tu navegador a http://localhost:3000 y deberías tener la aplicación ejecutándose. Haz clic en los enlaces de inicio de sesión y registro en la página, y se deben mostrar las páginas respectivas.

Paso 2: Implementando la funcionalidad del registro

Para implementar la funcionalidad de registro, llamaremos a la API REST de Python Eve. Llamaremos a esta API desde el back-end de Node.js, ya que requiere pasar el nombre de usuario y la contraseña de autenticación del servicio. Entonces, para evitar exponer el nombre de usuario de autenticación y la contraseña de los scripts, haremos esta llamada desde Node.js.

Primero creemos un controlador register para la solicitud de tipo POST y así manejar la funcionalidad de registro.

1
app.post('/register', function(req, resp) {
2
   // Code will be here

3
});

Necesitaremos body-parser para analizar los datos enviados desde el formulario. Instala body-parser usando el administrador de paquetes NPM.

1
npm install body-parser

Una vez que se haya instalado body-parser, solicítalo dentro de app.js.

1
bodyParser = require('body-parser')

Para usar body-parser para analizar los datos enviados desde el formulario, debemos usarlo en nuestra aplicación.

1
app.use(bodyParser.urlencoded({
2
    extended: true
3
}));

Dentro del controlador /register podemos analizar los datos del formulario como se muestra a continuación:

1
var _firstName = req.body.inputFirstName;
2
var _lastName = req.body.inputLastName;
3
var _username = req.body.inputUsername;
4
var _password = req.body.inputPassword;
5
var _phone = req.body.inputPhone;

Usaremos request para realizar la llamada a las API de Eve. Así que instala request en la aplicación.

1
npm install request

Requerir request en app.py.

1
request = require('request')

Crea las opciones para llamar a la API como se muestra a continuación:

1
var options = {
2
    url: 'http://127.0.0.1:5000/user/',
3
    method: 'POST',
4
    auth: {
5
        user: 'admin',
6
        password: 'admin'
7
    },
8
    formData: {
9
        firstname: _firstName,
10
        lastname: _lastName,
11
        username: _username,
12
        password: _password,
13
        phone: _phone
14
    }
15
}

Hemos especificado los detalles de la solicitud POST en las opciones. admin_username y admin_password son el nombre de usuario de autenticación y la contraseña necesarios para acceder a la API en la creación de usuarios de Eve.

A continuación, vamos a usar request para realizar la llamada.

1
request(options, function(err, res, body) {
2
    if (err) {
3
        console.log(err);
4
        return;
5
    }
6
    console.log('Response: ', res)
7
    console.log('Returned data: ', body)
8
})

Guarda los cambios y reinicia el servidor. Apunta tu navegador a http://localhost:3000 y navega hasta la pantalla de registro. Ingresa los detalles y haz clic en el botón de registro. Consulta la ventana de la terminal para ver la respuesta y los detalles de creación del usuario devueltos por la llamada a la API.

Paso 3: Manejando errores en el registro

Cuando ocurre un error durante el proceso de registro, pasaremos el mensaje de error a la página de registro. Usaremos un motor de plantillas llamado EJS. Primero, instalemos EJS.

1
npm install ejs

Una vez que hayas terminado con la instalación de EJS, agrega la siguiente línea de código para configurar la carpeta 'view' y el motor de vistas de plantilla.

1
var path = require('path');
2
app.set('views', path.join(__dirname + '/public/signup'));
3
app.set('view engine', 'ejs');

Cambia el nombre de signup.html a signup.ejs y agrega una etiqueta 'span' para mostrar un error después del botón Enviar.

1
<span style="color:red;"><%= error %></span>

Además, modifica el controlador de solicitudes signUp.

1
app.get('/signUp',function(req,res){
2
    res.render('signup',{error:''})
3
});

Luego, si ocurre algún error en la respuesta de registro, lo pasaremos a la página de registro. Si el proceso de registro no arroja ningún error, redirigiremos al usuario a la página de inicio de sesión.

1
request(options, function(err, res, body) {
2
    if (err) {
3
        return resp.render('signup', {
4
            error: err
5
        })
6
    }
7
    var result = JSON.parse(body)
8
    if (result._status == 'ERR') {
9
        if (result._error.code == '400') {
10
            return resp.render('signup', {
11
                error: 'Username Already Exists!'
12
            })
13
        }
14
        return resp.render('signup', {
15
            error: result._issues.username
16
        })
17
    } else {
18
        console.log('All good');
19
        resp.redirect('/signIn');
20
    }
21
})

Guarda todos los cambios y reinicia el servidor. Apunta tu navegador a http://localhost:3000/signUp e intenta registrarte usando un nombre de usuario existente. Dado que el nombre de usuario ya existe, deberías recibir un error.

Username already exists error on Sign UpUsername already exists error on Sign UpUsername already exists error on Sign Up

Creando la aplicación AngularJS

Implementando la funcionalidad de inicio de sesión

AngularJS proporciona un servicio llamado $http que ayuda a realizar llamadas a la API REST. De los documentos de AngularJS,

El servicio $http es un servicio central de Angular que facilita la comunicación con los servidores HTTP remotos a través del objeto XMLHttpRequest del navegador o mediante JSONP.

Copia el contenido del body del archivo index.html y crea un nuevo archivo llamado public/home/home.html.

1
<div class="container">
2
    <div class="header">
3
        <nav>
4
            <ul class="nav nav-pills pull-right">
5
                <li role="presentation" class="active"><a href="#">Home</a></li>
6
                <li role="presentation"><a href="#/signin">Sign In</a></li>
7
                <li role="presentation"><a href="/signUp">Sign Up</a></li>
8
            </ul>
9
        </nav>
10
        <h3 class="text-muted">Angular Node App</h3>
11
    </div>
12
13
    <div class="jumbotron">
14
        <h1>Angular Node App</h1>
15
        <p class="lead"></p>
16
        <p><a class="btn btn-lg btn-success" href="/signUp" role="button">Sign up today</a></p>
17
    </div>
18
19
20
21
    <footer class="footer">
22
        <p>&copy; Company 2015</p>
23
    </footer>
24
25
</div>

En la carpeta 'home', crea un archivo llamado home.js y define el módulo home y la configuración de rutas como se muestra a continuación:

1
'use strict';
2
3
angular.module('home', ['ngRoute'])
4
5
.config(['$routeProvider', function($routeProvider) {
6
  $routeProvider.when('/home', {
7
    templateUrl: '../home/home.html',
8
    controller: 'HomeCtrl'
9
  });
10
}])
11
12
.controller('HomeCtrl', [function() {
13
14
}]);

De manera similar, reemplaza el código HTML de signin.html con el contenido del body de signin.html. Manejaremos el enrutamiento de la página de inicio de sesión a través de la aplicación AngularJS.

Dentro de la carpeta signin, crea un archivo llamado signin.js y agrega los siguientes detalles de configuración de ruta.

1
'use strict';
2
3
angular.module('signin', ['base64','ngRoute','myAppService'])
4
5
.config(['$routeProvider', function($routeProvider) {
6
  $routeProvider.when('/signin', {
7
    templateUrl: '../signin/signin.html',
8
    controller: 'SignInCtrl'
9
  });
10
}])
11

En index.html usaremos ngView y direccionaremos las vistas de la aplicación AngularJS. Así es como se verá index.html:

1
<!DOCTYPE html>
2
<html lang="en" ng-app="myApp">
3
  <head>
4
    <title>Angular Node App</title>
5
6
   
7
    <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
8
9
    <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
10
    <script src="https://code.jquery.com/jquery-2.0.1.min.js"></script>
11
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
12
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.js"></script>
13
    <script src="home/home.js"></script>
14
    <script src="signin/signin.js"></script>
15
    <script src="index/index.js"></script>
16
    
17
  </head>
18
19
  <body>
20
21
    <div ng-view></div>
22
  </body>
23
</html>

Dentro de la carpeta index, crea un archivo llamado index.js que servirá como archivo raíz. En index.js inyectaremos los diferentes módulos creados en la aplicación myApp. Aquí está el archivo index.js:

1
angular.module('myApp', [
2
  'ngRoute',
3
  'home',
4
  'signin'
5
]).
6
config(['$routeProvider', function($routeProvider) {
7
  $routeProvider.otherwise({redirectTo: '/home'});
8
}]);

Instala angular-route usando bower e incluye la referencia en index.html.

1
bower install angular-route
1
<script src="../bower_components/angular-route/angular-route.js"></script>

También necesitaremos convertir el nombre de usuario y la contraseña a base64, así que instala angular-base64.

1
bower install angular-base64

Una vez instalado, agrega una referencia a angular-base64 en index.html.

1
<script src="../bower_components/angular-base64/angular-base64.js"></script>

Establece la ruta estática a bower_components en app.js.

1
app.use('/bower_components',  express.static(__dirname + '/bower_components'));

Dentro de signin.js, creemos un controlador llamado SignInCtrl.

1
'use strict';
2
3
angular.module('signin', ['base64','ngRoute'])
4
5
.config(['$routeProvider', function($routeProvider) {
6
  $routeProvider.when('/signin', {
7
    templateUrl: '../signin/signin.html',
8
    controller: 'SignInCtrl'
9
  });
10
}])
11
12
.controller('SignInCtrl',['$scope','$http','$base64',function($scope,$http,$base64){
13
}]);

Acabamos de crear un controlador llamado SignInCtrl en signin.js. Hemos inyectado el módulo base64 en SignInCtrl.

Al hacer clic en el botón de inicio de sesión, llamaremos a la función signIn anterior para autenticar al usuario. Entonces, primero agreguemos la directiva ngModel al campo del nombre de usuario y la contraseña en la página de inicio de sesión.

1
<input type="text" name="inputUsername" id="inputUsername" ng-model="username" class="form-control" placeholder="Email address"  autofocus>        
2
<input type="password" name="inputPassword" id="inputPassword" ng-model="password" class="form-control" placeholder="Password" >

Agrega la directiva ngClick al botón de iniciar sesión en signin.html.

1
<button id="btnSignIn" class="btn btn-lg btn-primary btn-block" ng-click="signIn()">Sign in</button>

Dentro de la función signIn, lee el nombre de usuario y la contraseña de $scope. Una vez que tengamos el nombre de usuario y la contraseña, crearemos la cadena base64 usando angular-base64.

1
$scope.signIn = function() {
2
  
3
    var username = $scope.username;
4
    var password = $scope.password;
5
6
    var authdata = $base64.encode(username + ':' + password);
7
}

Antes de realizar una llamada a las API REST, debemos configurar los encabezados necesarios. Necesitamos configurar Access-Control-Request-Headers y Access-Control-Expose-Headers.

1
$http.defaults.headers.common = {"Access-Control-Request-Headers": "accept, origin, authorization"};
2
3
$http.defaults.headers.common = {"Access-Control-Expose-Headers": "Origin, X-Requested-With, Content-Type, Accept"};
4
5
$http.defaults.headers.common["Cache-Control"] = "no-cache";
6
7
$http.defaults.headers.common.Pragma = "no-cache";

También necesitaremos establecer el encabezado Authorization en $http. Usando el authData de base64 creado con username y password, configura el encabezado de autorización.

1
$http.defaults.headers.common['Authorization'] = 'Basic '+authdata;

A continuación, realiza la llamada GET mediante $http a las API REST de Python Eve.

1
$http({
2
    method: 'GET',
3
    url: 'http://127.0.0.1:5000/user/' + username
4
}).
5
success(function(data, status, headers, config) {
6
    console.log(data);
7
}).
8
error(function(data, status, headers, config) {
9
    console.log(data, status);
10
});

Guarda todos los cambios y reinicia el servidor. Apunta tu navegador a http://localhost:3000/signin. Intenta iniciar sesión con un nombre de usuario y una contraseña válidos. Verifica la consola del navegador y deberías tener los datos del usuario. Si la autenticación falla, deberías tener un error de autenticación.

Conclusión

En este tutorial, vimos cómo usar las API REST creadas en el tutorial anterior en nuestra aplicación AngularJS y Node.js. Implementamos la funcionalidad de inicio de sesión y registro en este tutorial.

En la siguiente parte de esta serie, usaremos las otras API para completar nuestra aplicación AngularJS.

El código fuente de este tutorial está disponible en GitHub.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.