Archivo de la etiqueta: javascript

Importando el calendario de nuestro evento favorito

El próximo 27 y 28 de noviembre estaré un año más en el Codemotion, un evento que se celebra en Madrid reúne comunidades de todo tipo y del que hemos hablado en otros artículos de años anteriores.

En ellas desarrolladores de .NET, Java y la JVM, Ruby, Python, JavaScript, Objective-C, Swift, PHP y otros, se reunen para enseñarnos lo mejor de todos los mundos. Yo ya tengo mi entrada, si no tienes la tuya ya estás tardando

Sin embargo hay algo que sigo sin entender. Al igual que en otros eventos, tenemos disponible la agenda completa en la web, y probablemente el primer día nos entregarán una copia EN PAPEL que acabará en una papelera varios días después del evento, si no lo perdemos antes.

No sería mucho más conveniente poder tener el calendario oficial del evento en un formato que lo pudiera entender nuestro Google Calendar, Outlook, iCal o cliente que utilicemos, y poder usar nuestro móvil para orientarnos por el evento? Pues bien, eso es lo que he hecho, y es lo que veremos en este artículo:

Primer paso, obtener los datos

Para obtener los datos originales tenemos muchas maneras. Una de ellas es utilizar un servicio como Kimono que nos permite crear una API REST a partir de una página ya existente, lo cual nos puede resultar muy útil para extraer información.

Otra opción consiste en investigar un cómo, y qué datos carga la página. En el caso de Codemotion, la agenda se carga de manera asíncrona, así que tras investigar el panel de red de Chrome podemos ver un fichero en formato JSON que contiene, para nuestro disfrute, la agenda completa a nuestra disposición, así que, misión cumplida.

Segundo paso, comprender el formato de salida

Para poder generar un fichero que sea compatible con los diferentes clientes de email, una de las opciones es utilizar el formato icalendar, que define un evento de la siguiente manera:

BEGIN:VEVENT
SUMMARY:Document like a hero using Asciidoctor
DTSTART:20151127T160000Z
DTEND:20151127T164500Z
DESCRIPTION:In 2013, the Spring team decided to migrate the Starting Guides on spring.io ...
END:VEVENT

Analicemos los diferentes componentes, dejando de lado las cabeceras begin y end del evento:

  • Summary: Título que se mostrará en la cita del calendario
  • Dtstart: Fecha y hora de inicio de la cita en la zona horaria UTC, en el siguiente formato: Año Mes Día (T) Hora Minutos Segundos (Z)
  • Dtend: Fecha y hora de fin de la cita, en el mismo formato anteriormente comentado
  • Description: Detalles del evento

Si hemos utilizado el calendario de manera corporativa echaremos de menos temas como invitados, alarmas, etc, aunque todos ellos forman parte del estándar y podemos utilizarlos sin problemas. Para reunir varios eventos en un fichero iCalendar hemos de establecer unas cabeceras y un pie de página de la siguiente manera:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
...
END:VCALENDAR

En este código, definimos nuestro fichero iCalendar, la versión del mismo, y el identificador del generador (que en este caso lo he tomado directamente del ejemplo de la wikipedia). Cerramos el fichero con el marcador End.

Con esta información, ya podemos generar nuestro calendario.

Tercer paso, generar el calendario

Para este ejemplo, como utilizaba un fichero en formato json, me pareció mucho más sencillo utilizar JavaScript y Node.js para generar el fichero ics.

Una de las cosas que nos aporta JavaScript, es que, al ser dinámicamente tipado, podemos abstraer la consola en un objeto creado por nosotros, y asignarlo o no a la consola en función de nuestra necesidad.

Como detalle a tener en cuenta está el uso de saltos de línea, ya que hemos de utilizar \n, de otra manera, se generará una nueva línea en el fichero de texto resultante y tendremos un error al importarlo.

Además, aunque parezca obvio, podemos tener más de un evento en un mismo fichero ics.

Cuarto paso, probarlo

Por último, y no por ello menos importante, es necesario confirmar que nuestro calendario se ha generado correctamente, para lo que podemos utilizar servicios como iCalendar validator. Finalmente recomiendo utilizar alguna aplicación de escritorio (como iCal en Mac) para hacer un par de importaciones y comprobar que todos los eventos se generan correctamente.

Conclusiones

Podemos generar un calendario utilizando el formato ics y teniendo una fuente de origen de datos. Si nuestra fuente está en formato json, podemos utilizar JavaScript de manera sencilla para movernos por el mismo, y generar nuestro fichero de resultado, que, por cierto, tienes disponible públicamente en Github.

Yo ya tengo mi calendario, y tú?

Enlaces adicionales:

Anuncios

Kanwal, mi propio Trello dentro del firewall

He de reconocer que soy un gran fan de Trello, un tablero de Kanban personalizable que me permite organizar mi agenda, mis objetivos personales, los viajes, las charlas, mis proyectos y los regalos de navidad, entre otros.

Sin embargo, para uso profesional he descubierto que muchas empresas que no permiten guardar información relacionada con proyectos en servicios en la nube, y para ello he creado un pequeño clon de Trello llamado Kanwal, para poderlo utilizar de manera segura dentro el firewall.

Para poder empezar a utilizarla necesitaba, como mínimo, las siguientes características:

  • Aregar listas
  • Agregar elementos a las listas
  • Borrar elementos de las listas

Características como mover un elemento de lista o editar elementos pueden ser muy chulas, aunque entrarán en la siguiente versión.

Con esa máxima tocaba escoger armas, y en mi caso fueron dos que ya había utilizado anteriormente:

  • Knockout.JS: Un framework MVVM muy sencillo y ligero que me permite realizar data-bindings de manera rápida y fácil
  • Bootstrap: Un framework CSS que me permite dar una estructura y un aspecto básicos a la web.
  • Yeoman: Una herramienta que nos permite crear proyectos con diferentes frameworks de manera rápida y sencilla.

Con las armas escogidas, tocaba ponerse manos a la obra, y un par de horas después la aplicación (si es que podemos llamarla aplicación) tenía este aspecto: Espartano, básico, pero es todo lo que necesito para empezar a trabajar:

kanwall-v1

La arquitectura es muy simple:

Una tarea:

  • Es una cadena de texto simple

Una lista:

  • Es un Viewmodel que contiene un título y una lista de tareas.
  • Contiene un método para agregar tareas, para borrarlas y para renombrar la lista, pasando a un sencillo “modo edición”.
  • Contiene una referencia al método guardar del viewmodel global.

El viemodel global:

  • Es una lista de listas.
  • Contiene Métodos para guardar y cargar los datos de local storage.

Como curiosidad, el nombre original era Kan-Wall (de Kanban firewall), aunque gracias a la corrección de Google descubrí que el nombre (con una L) correspondía a una región de Australia, así que así se ha quedado.

Le puedes echar un vistazo a la aplicación en rlbisbe.github.io/kanwal y ver el código fuente en github.
Si estás interesado en ayudar, envíame una pull request!

Have fun!

Explicando Promises de JavaScript con un ejemplo simple

Hace unos días tuve la oportunidad de ver, una vez más, explicado el concepto de promesas y de objetos asíncronos, cuyo objetivo es, entre otros, evitar el llamado “callback-hell” que surge cuando llamamos a una función asíncrona en JavaScript.

En nuestro código frontend, es bastante habitual encontrarnos con funciones con este aspecto:

function myFunction(arguments,onSuccess,onError){
//Do things...
}

myFunction({val: 12}, function(){
    //Do things on success
}, function(){
    //Do things on error
});

El problema surge cuando encadenamos varias llamadas asíncronas, y ya no somos capaces de saber en qué función estamos ní cómo hemos llegado allí, además que el código se hace más difícil de leer.

Las promises o promesas, son objetos que nos permiten mejorar la legibilidad de nuestro código y evitar tener que pasar el contenido de las funciones directamente como argumentos a nuestra llamada.

En este artículo veremos una implementación muy simple de una promesa, para ver cómo funciona realmente, y comprobar que la base es un objeto simple con ciertas propiedades.

Nuestra clase Promise

Veamos por encima qué tenemos en nuestra clase Promise:

function Promise(){

    var self = this;
    var thenCallback = null;

    self.then = function(callback){
        thenCallback = callback;
    };

    self.complete = function(args){
        if (thenCallback && typeof thenCallback === 'function'){
            thenCallback(args);
        }
    };
}

Esta clase define dos funciones, una función then, en la que especificamos la función a ejecutar al terminar la acción, y una función complete, que nos permite ejecutar la función que hayamos definido, pasandole los argumentos necesarios.

Veamos un ejemplo de uso:

function myFunction(){

    var p = new Promise();
    setTimeout(p.complete, 1000)
    return p;
}

var promise = myFunction()
promise.then(function(){
    console.log('done');
});

En este caso, por una parte simulamos una llamada asíncrona con la función setTimeout, y por otra parte devolvemos la promesa. En el código que llama a la función, nos suscribimos al resultado de esa promesa, y podemos separar la ejecución de la función del tratamiento del resultado de la misma.

Gestión de errores y encadenamiento de promesas

Además de ejecutar funciones cuando todo ha ido bien, hemos de ser capaces de ejecutar acciones cuando se ha producido un error.

Para ello solamente tenemos que extender nuestra clase, agregando dos funciones adicionales, una se suscriba al error, que llamaremos error, y otra que ejecute la acción de error, que llamaremos fail.

self.error = function(callback){
        failCallback = callback;
};

self.fail = function(args){
    if (failCallback && typeof failCallback === 'function'){
        failCallback(args);
    }
}

Por otra parte, mediante un pequeño cambio podemos encadenar resultados:

self.error = function(callback){
        failCallback = callback;
        return self;
};

Este encadenamiento nos permite tener interfaces más fluidas, de tal manera que por una parte nos suscribimos al resultado de una función, y por otra parte al posible error:

promise.then(function(args){
    console.log('foo has happened ' + args);
}).error(function(args){
    console.log('error has happened');
});

Funciones “always”

Además de código que se ejecute cuando todo ha ido bien, o cuando todo ha ido mal, es posible que necesitemos código que se ejecute siempre, independientemente del resultado, lo que sería equivalente a la directiva “finally” de una función de C#.

Para ello solamente necesitamos agregar un nuevo callback a nuestra lista, que se ejecutará en caso de éxito o de fallo.

Conclusiones

Como vemos, las promesas no son “magia” que tienen algunas bibliotecas de JavaScript. Simplemente es otra sintaxis, otra manera de recuperar el control tras volver de una función asíncrona.

Si echamos un vistazo a lo que se propone para ECMAScript 6, lo que en la práctica será la próxima versión de JavaScript, veremos que las ideas son muy similares a lo que hemos visto en este artículo, aunque más extendido y detallado.

Tienes el código completo de la promesa en este gist

Enlaces adicionales

Diferentes tipos de “Promises”

Gracias a Antón Molleda (@molant) por los enlaces!

Vídeos y material de “Lecciones aprendidas creando una red social” con MadridJS

Este jueves he podido compartir con los chicos de MadridJS así como varios alumnos del programa Ironhack, nuestra experiencia con javascript desarrollando una red social enfocada al desarrollo científico. Durante poco menos de una hora (y luego durante las cañas) repasamos herramientas, metodologías, y pruebas que hacemos en nuestros sistemas, así como las lecciones que hemos aprendido en el camino. En este artículo podrás encontrar el vídeo del evento, las slides de slideshare así como enlaces adicionales de temas que surgieron durante el mismo.

El debate fue muy interesante y personalmente he descubierto un montón de cosas nuevas para estudiar, gracias a todos los asistentes.

Vídeo

Slides

Enlaces adicionales de temas que surgieron en la charla:

Evento para acabar el año: Lecciones aprendidas creando una red social

global_139815902

El próximo jueves 18 a las 19:00 vuelvo a MadridJS en mi última charla del año, en la que veremos algunas lecciones aprendidas tras haber estado durante varios meses involucrado en el desarrollo de una red social.

En esta sesión veremos algunas tecnologías, frameworks y herramientas que hemos usado tanto para desarrollar, hacer pruebas tanto unitarias como de aceptación, y finalmente para temas relacionados con despliegue de la parte frontend de la plataforma, así como algunas anécdotas y problemas a los que nos enfrentamos en los diferentes procesos tanto de creación del portal como de puesta en producción.

Además, veremos herramientas y librerías como knockout, sammy, qunit, sinon y selenium.

Inscríbete en: http://www.meetup.com/madridjs/events/219137077/

Te espero allí!

Adding multiple languages to a Windows Store app with Javascript and Angular

Leer este artículo en castellano aqui

Last thursday I could attend a debate organized by MSCoders Madrid user group, related with localization of apps in a web enfironment.

After the event I got interested in frontend localization with Javascript. As Karmacracy for Windows is a Javascript app, I decided to do some experimentation on localizing the user interface in the context of a Windows Store app, to be able to distribute it for other markets.

Detecting the system language

For a Windows Store app the first thing to do is to detect the sustem language. This can be archieved with the following piece of code:

var culture = Windows.System.UserProfile.GlobalizationPreferences.languages[0];
var language = culture.substr(0, 2);

The culture is the language that is currently being used for the UI, in culture format. For example for Spanish of Spain would be es-ES, for US English would be en-US, and for British English would be en-GB. To be able to change this order and deploy our app, we must go to the control panel:

Captura de pantalla 2014-09-15 00.29.43

In this example we only need the language, not the culture, so we are going to get a substring of the culture getting en, es, de, etc.

Adding angular-translate

Angular-translate is a module that allows us to define key-value pairs for each language and perform the translation according to the configuration. For installing it, if we don’t use a package manager such as bower, we must download the last package from github and add it to our project.

Once installed, we must add it to the configuration of our app, in the section we define external modules (in this case the module is pascalprechtr.translate).

var karmacracyApp = angular.module('karmacracyApp', [
    'ngRoute',
    'karmacracyControllers',
    'pascalprecht.translate'
]);

Finally, we configure the different languages by using the code we defined previously for getting the OS display language:

karmacracyApp.config(['$translateProvider', function ($translateProvider) {
    $translateProvider.translations('en', {
        'LOGIN': 'Log in',
        'LOGIN_USERNAME': 'User name',
        'LOGIN_PASSWORD': 'Password'
    });

    $translateProvider.translations('es', {
        'LOGIN': 'Inicia sesión',
        'LOGIN_USERNAME': 'Nombre de usuario',
        'LOGIN_PASSWORD': 'Contraseña'
    });

    var culture = Windows.System.UserProfile.GlobalizationPreferences.languages[0];
    var language = culture.substr(0, 2);

     $translateProvider.preferredLanguage(language).fallbackLanguage('en');
}]);

Also, in case the current language is not available, we set English by default

#Usage

For accessing our keys we don’t need any aditional configuration on our controllers, we just need to modify our views so they can access the localized information

<span class="loginMessage">{{ 'LOGIN' | translate }}</span>

If the language is set to English or other language not controlled, the result will be the following:

en

If the language is set to spanish, the result will be the following:

es

As it shows, is an easy way to localize our javascript apps for the Windows Store.

Recap and next steps

Angular-translate provides a simple way of localizing texts in our views and Windows provides the information we need for setting the current language of an app.

As an aditional step, we may try to localize winjs controls such as buttons, which work in a very different way. Angular-translate also supports loading the translations from a json files, an option that may be useful if we want to distribute those files for translation by 3rd parties.

Links

Agregando múltiples idiomas a una aplicación de Windows Store con Javascript y Angular

**Read this article in English here

El pasado jueves tuve la ocasión de asistir a una mesa redonda organizada por el grupo MSCoders relacionada con la localización de aplicaciones en entornos web.

Tras el evento, uno de los temas que más llamó mi atención fue la localización en la parte Javascript, y como tenía una aplicación ya en la Windows Store que usaba ese lenguaje, me pareció interesante intentar localizarla para poder ofrecerla en otros mercados.

Detectando el idioma del sistema

Para una aplicación Windows 8 el primer paso es detectar el idioma del sistema, y eso lo podemos hacer de la siguiente manera:

var culture = Windows.System.UserProfile.GlobalizationPreferences.languages[0];
var language = culture.substr(0, 2);

En este caso tomaremos la lista de lenguajes preferentes, y de esa lista obtendremos el primer elemento. Para poder cambiar el orden de los elementos y probar los diferentes lenguajes, podemos cambiarlo en el panel de control:

Captura de pantalla 2014-09-15 00.29.43

El resultado se muestra en formato cultura, es decir, español de España se mostraría como es-ES, e inglés de EEUU se mostraría como en-US. Para nuestro ejemplo inicial, solamente necesitamos el idioma, con lo cual hacemos un substring y obtenemos en o es respectivamente.

Agregando angular-translate

Angular-translate es un módulo de angular que nos permite definir de manera las claves y los valores para cada lenguaje, y realizar la traducción en función de la configuración. Para instalarlo, si no contamos con gestores de paquetes como bower, es tan sencillo como descargar el último paquete de github y agregarlo a nuestro proyecto.

Una vez instalado, tendremos que agregarlo a la configuración de nuestra app, en el apartado en el que definimos módulos externos en este caso pascalprecht.translate:

var karmacracyApp = angular.module('karmacracyApp', [
    'ngRoute',
    'karmacracyControllers',
    'pascalprecht.translate'
]);

Finalmente, configuramos los diferentes idiomas usando el código que hemos visto anteriormente para seleccionar un idioma acorde con el sistema operativo:

karmacracyApp.config(['$translateProvider', function ($translateProvider) {
    $translateProvider.translations('en', {
        'LOGIN': 'Log in',
        'LOGIN_USERNAME': 'User name',
        'LOGIN_PASSWORD': 'Password'
    });

    $translateProvider.translations('es', {
        'LOGIN': 'Inicia sesión',
        'LOGIN_USERNAME': 'Nombre de usuario',
        'LOGIN_PASSWORD': 'Contraseña'
    });

    var culture = Windows.System.UserProfile.GlobalizationPreferences.languages[0];
    var language = culture.substr(0, 2);

    $translateProvider.preferredLanguage(language).fallbackLanguage('en');
}]);

Además, en caso de que el sistema tenga un idioma no controlado, estableceremos el inglés por defecto.

Uso

Para acceder a nuestras claves no necesitamos realizar ninguna configuración adicional en nuestros controladores, solamente necesitamos modificar nuestras vistas para que accedan a la información localizada:

<span class="loginMessage">{{ 'LOGIN' | translate }}</span>

En caso de que tengamos el idioma establecido a inglés (o a cualquier idioma no controlado), se mostrará el siguiente resultado:

en

En caso de que el idioma esté establecido a español, el resultado será diferente:

es

Como se ve, es una manera sencilla de poder localizar nuestras aplicaciones en javsacript para Windows Store

Conclusiones y pasos adicionales

Angular-translate proporciona una manera sencilla de localizar textos en nuestras vistas, por otra parte, Windows proporciona, a través de su API, la información que necesitamos para saber en qué idioma mostrar una aplicación.

Un paso adicional sería localizar controles winjs como los botones, que funcionan de manera diferente. Por otra parte se podría sacar un fichero de traducciones fuera de la configuración en formato json, útil si queremos distribuir esos ficheros para su procesamiento.

Enlaces adicionales