API REST SIN UNA LÍNEA DE CÓDIGO… DEL LADO BACKEND!. PARTE 2. FRONTEND

< script src=”my own” title=”api rest sin una l&iacute;nea de c&oacute;digo”>

Entender el estilo arquitectónico REST es retador, ya que requiere entender ampliamente (por ejemplo) la transmisión y recepción sin estados que maneja el protocolo (en este caso, HTTP) seleccionado. Tanto más retador es desarrollar una API REST enteramente Backend para interactuar con tu aplicación Frontend (que casi siempre es la que requiere un poco más de atención ^^’ ).

En este caso, vamos a prestarle más atención a la aplicación Frontend realizada para el ejemplo del post anterior a esta serie, en en cual creamos una data-app con JEXIA. Para esta aplicación, usé Minified.js, y min.css, dos herramientas que están que ni pintadas para hacer mockups y otras cosillas #porai. ¡Manos a la ubre!

El código de la interfaz es sencillo:

<!DOCTYPE html>
<html lang="es">
<head>
	<meta charset="UTF-8">
	<link rel="stylesheet" href="entireframework.min.css">
	<title>Ejemplo con Minified</title>
</head>
<body>

<div><span id="notificacion"></span></div>


<div class="container">

<h2>¿Cuáles son tus gustos musicales?</h2>


<div id="lista"></div>

		<button id="seleccionar" class="btn btn-b btn-sm"><i>✓</i> Listo!</button>
		<button id="calcular" class="btn btn-b btn-sm"><i>◴</i> Ver resultados</button>
	</div>


<div id="form" class="container">
		<input type="text" name="nombre" id="nombre" placeholder="Ingrese su nombre">&nbsp;<button class="btn btn-b btn-sm" id="procesar"><i>✓</i>Procesar!</button>
	</div>


<div class="container" id="result"></div>

	<script src="minified.js"></script>
	<script src="api.js"></script>
</body>
</html>

El código Javascript que procesa la información haciendo peticiones a la API REST es un poco más complejo:

var MINI = require('minified');

var $ = MINI.$, $$ = MINI.$$, HTML = MINI.HTML;

var auth = {
	key: 'd0847280b3734ffb15b496caf2839a8a',
	secret: '*secret key*'
}
var baseUrl = 'http://4a2d78b0-9ddf-11e5-a58a-89db67e6a459.app.jexia.com';

$(function() {
	$('#nombre').set('value', '');

	var toggleForm = $('#form').toggle(
		{'$$slide': 0},
		{'$$slide': 1},
		500
	);

	var toggleAlert = $('#notificacion').toggle(
		{'$$fade': 0},
		{'$$fade': 1},
		500
	);

	var toggleResult = $('#result').toggle(
		{'$$fade': 0},
		{'$$fade': 1},
		500
	);

	function notificar(objMensaje) {
		$('#notificacion').ht(errorTm, objMensaje);
		toggleAlert(); setTimeout(toggleAlert, 3000);
	};

	function reiniciarFormulario(lista, elegidos) {
		toggleForm();
		$('#nombre').set('value', '');
		lista.each(function (item, index){
			item.disabled = false;
			item.checked = false;
		});
		elegidos = [];
	};

	var opcionesTm = '
<div class="row">{{each}}
<div class="col c2"><input type="checkbox" id="{{this.opcion}}" value="{{this.opcion}}" {{if !this.habilitada}}disabled="true"{{/if}}><label for="{{this.opcion}}">&nbsp;{{this.texto}}</label></div>

{{/each}}</div>

';

	var errorTm = '
<div class="msg {{type}}">{{msg}}</div>

';

	var resultTm = '{{var total = datos.Pop + datos.Rock + datos.Clasica + datos.Jazz;}}
<h2>Total: {{total}} voto{{if total > 1 || total == 0}}s{{/if}}</h2>
<div class="row">{{each clave, valor: datos}}{{var w = (valor * 100)/total;}}
<div class="col c3">
<div>{{clave}}: {{valor}} voto{{if valor > 1 || valor == 0}}s{{/if}} / {{w::#.00}}%</div>
<div style="width: {{w::#.00}}%; background-color: green;">&nbsp;</div>
</div>

{{/each}}</div>

';

	var settings, opciones = [], key = '-';
	$.request('POST', baseUrl, auth).then(function(text) {
			var data = $.parseJSON(text);
			settings = { headers: { 'Authorization': 'Bearer ' + data.token } };
			return $.request('GET', baseUrl + '/opciones', null, settings);
		}
	).then(function (text) {
			var data = $.parseJSON(text);
			$('#lista').add(HTML(opcionesTm, data));
			var elegidos = [], lista = $('input[type=checkbox]');

			$('#seleccionar').onClick(function() {
				lista.each(function (item, index) {
					if (item.checked) elegidos.push(item.value);
				});
				if (elegidos.length === 0) {
					notificar({
						type: 'error',
						msg: 'Seleccione al menos una opcion'
					});
				}	else {
					lista.each(function (item, index){
						item.disabled = true;
					});
					toggleForm();
				}
			});

			$('#procesar').onClick(function (){
				var nombre = $('#nombre').get('value');
				if(nombre) {
					var data = {
						nombre: nombre,
						elegidos: elegidos.join(key)
					};
					$.request('POST', baseUrl + '/resultados', data, settings)
					.then(function (text){
						notificar({
							type: 'done',
							msg: 'Sus datos han sido procesados exitosamente! ☺'
						});
						setTimeout(reiniciarFormulario(lista, elegidos), 1500);
					}).error(function (code, text){
						var data = $.parseJSON(text);
						notificar({
							type: 'error',
							msg: 'Error ' + code + ': ' + data.summary
						});
					});
				} else {
					$('#nombre').set('+error');
					notificar({
						type: 'error',
						msg: 'El nombre es requerido para el registro'
					});
				}
			});

			$('#calcular').onClick(function () {
				toggleResult();
				$.request('GET', baseUrl + '/resultados', null, settings)
				.then(function (text) {
					var data = $.parseJSON(text);
					var graphData = [];
					$(data).each(function (item, index){
						graphData.push(item.elegidos.split(key));
					});
					graphData = $(graphData).array().reduce(function(count, elem){
						elem = elem === '1' ? 'Pop' :	elem === '2' ? 'Rock' :	elem === '3' ? 'Clasica' : 'Jazz';
      				count[elem] = (+count[elem] || 0) + 1; return count;
					}, {});
					$('#result').ht(resultTm, {datos: graphData});
				})
				.error(function (code, text) {
					var data = $.parseJSON(text);
					notificar({
						type: 'error',
						msg: 'Error ' + code + ': ' + data.summary
					});
				});
			});
		}
	)
	.error(
		function(code, text){
			var data = $.parseJSON(text);
			notificar({
				type: 'error',
				msg: 'Error ' + code + ': ' + data.message
			});
		}
	);
});

Veamos los resultados en el navegador:

9.1-app-minified-encuesta

Se cargan los resultados de la primera data-app creada (musica)

9.2-notificacion

Validación en caso de no marcar ninguna opción ^^’

9.3-valida-la-seleccion

Seleccionamos algunas opciones e ingresamos un nombre (¡importantísimo! 🙄 )

9.4-notificacion-con-error

Validamos nuevamente que el nombre sea el correcto y que además no esté vacío 😀

9.5-procesamiento-via-POST

Se almacenan los resultados en JEXIA via POST

9.6-REQUEST-a-resultados-y-template

Gracias a los templates de Minified.js, podemos ver los resultados dinámicamente, totalizando los datos guardados en la API REST 😀

¿Verdad que no fue tan difícil? Sabiendo que es posible, ahora podemos usar esta grandiosa app para lo que se nos ocurra, aprovechando las capacidades de su beta privada…

¡Felices API RESTfuls! 😉

</script>

Anuncios