How to access the value of an array key in a Javascript Map object?

I wrote this message in StackOverflow and just before clicking the Send button I stumbled upon the solution. I don’t want to lose it, and I don’t have time today to publish the solution, so I decided to do it in two parts. First, publish the question and later (tomorrow?) publish the solution. Here we go!

I can set() a value using an array as a key in a JS Map, but it seems that there isn’t a clean interface to access that same value using the symmetric get() method:

  let z = new Map {}
 
    z.set([1,2], "a"); // Works as expected: Map { [ 1, 2 ] => 'a' }
 
    z.get([1,2]); // undefined (!)

I suspect that this behaviour has something to do with the fact that in JS:

 [1,2] == [1,2] 
    false

I can use [1,2].toString() as a key and then the z.get([1,2].toString()) method works as expected, but I’m wondering if there is in any other «cleaner» way to code that.

UPDATE:
Well, Map objects are a new addition of ES6. And it seems that ES6 has a problem with Maps if you are trying to use them with object keys. This has been discussed here
https://esdiscuss.org/topic/maps-with-object-keys and here https://stackoverflow.com/questions/21838436/map-using-tuples-or-objects .

A solution that WorksForMe was proposed in that same StackOverflow thread, using an ad-hoc built HashMap class, that takes a hash function as parameter to properly store and use object keys (specifically, for my problem, array keys)

function HashMap(hash) {
  var map = new Map;
  var _set = map.set;
  var _get = map.get;
  var _has = map.has;
  var _delete = map.delete;
  map.set = function (k,v) {
    return _set.call(map, hash(k), v);
  }
  map.get = function (k) {
    return _get.call(map, hash(k));
  }
  map.has = function (k) {
    return _has.call(map, hash(k));
  }
  map.delete = function (k) {
    return _delete.call(map, hash(k));
  }
  return map;
}

I have used it as follows (note that JSON.stringify is NOT a hash function, but as I said, it works for my example because I certainly know that my array values are not going to have duplicates). I should think about a proper hash function or use something from here, but as I said, I’m lazy today 🙂

  let z = new HashMap(JSON.stringify);
  z.set([1,2], "a");
  z.get([1,2]); // "a"

Formateo y validación de objetos JSON

En esta ocasión, aprovechando que esta semana se estudia el formato JSON en una de mis clases, os quería recomendar un par de utilidades que utilizo a menudo: la herramienta jq y el plugin JSONView.

jq es una utilidad de la línea de comandos disponible para Linux, OS X y Windows que permite validar y visualizar de forma muy agradable objetos JSON. La mejor forma de apreciar el uso de jq es por medio de un ejemplo. En la siguiente figura, muestro un objeto JSON en la terminal sin usar jq. A continuación lo vuelvo a mostrar, esta vez filtrándolo con jq. Mucho mejor, ¿no?

Captura de pantalla 2016-03-07 a las 21.29.34

 

jq también detecta objetos JSON inválidos, marcando dónde se encuentra el error:

Captura de pantalla 2016-03-07 a las 22.00.40

JSONView es similar a jq, pero funciona como plugin o extensión, tanto de Google Chrome como de Mozilla Firefox. Veamos un ejemplo con el resultado de una llamada al API de OpenWeatherMap.

Sin usar JSONView:

Captura de pantalla 2016-03-07 a las 21.44.06

Con la extensión JSONView instalada:

Captura de pantalla 2016-03-07 a las 21.43.51

Sí, representan exactamente el mismo resultado. Pero uno es legible por humanos y el otro no 🙂

¿Conocíais estas utilidades? ¿Qué extensiones usáis en vuestros desarrollos? (HTML5, JS, PHP, whatever…)

Depurar, editar y guardar ficheros JS en Google Chrome

Receta rápida para los desarrolladores JavaScript interesados, y para retomar el blog tras un parón de unos cuantos meses (he estado ocupado 🙂

La cuestión es: las DevTools de Google Chrome permiten editar y depurar código JavaScript desde el propio navegador. Pero cuando editas un fichero .js y lo intentas guardar, salta el siguiente error:

chrome no deja grabar ficheros js «Changes to this file were not saved to file system». Vaya… pues qué bien… mmmmhh….  ¿y qué dice StackOverflow al respecto? Que existe una solución 🙂 Vamos allá…

Lo primero: pulsa en el botón de configuración.

Botón configuración

 

 

 

Lo segundo, elige la opción Workspaces y añade las carpetas con las que trabajas (las que contienen tu código JS):

carpeta dropbox

 

Puedes añadir más de una carpeta. Fíjate también que puedes editar mapeos URL –> Carpeta local, pero ahí no me meto (por ahora!)

Ojo, cuando añadas carpetas tendrás que aceptar dar permiso, para cada una, para que DevTools pueda acceder a esos datos en modo lectura/escritura. Esta ventana de solicitud de permisos aparece por debajo, en la ventana de Chrome, así que atento, porque hasta que no la pulses, la carpeta no se añadirá correctamente.

Selection_786 Ya casi está. Si estás usando el protocolo file:// para trabajar con tus ficheros en lugar de http://, ojo, porque en ese caso, deberás abrir tus archivos JS desde la carpeta que acabas de añadir al workspace (no vale abrir el fichero haciendo doble click sobre él desde el escritorio o tecleando la ruta en la barra de direcciones del navegador).

 

Abriendo workspaces Sino que tendrás que ir a la pestaña «Sources» y hacer doble click sobre los ficheros de las carpetas importadas (ojo, no desde file://)

Y a partir de ahora, cualquier cambio realizado en el panel DevTools podrás guardarlo «automágicamente» en el sistema de archivos local con un simple Ctrl+S.

 

Lynckia: vídeo conferencias en HTML5 (look ma! no plugins)

lynckia Lynckia (plataforma de comunicaciones de código abierto) permite realizar comunicaciones en tiempo real desde tu navegador usando la tecnología WebRTC. Aunque hasta hace poco sólo el navegador Google Chrome disponía de una implementación avanzada de WebRTC, desde el 4 de Febrero de este año podemos usar también el navegador Firefox. El 6 de Marzo (es decir, hace exactamente 10 días!) Google anunció el soporte WebRTC también en la versión de Chrome para Android.

Aún queda mucho trabajo por hacer (poder capturar streams RTMP y que formen parte de la videoconferencia, poder codificar los streams de los usuarios en uno sólo y no uno por cada usuario, ampliar la base de ejemplos…) pero los avances realizados hasta el momento por el equipo de Lynckia son impresionantes. Como decían en HTML5Spain:

Lynckia nos ha parecido uno de los proyectos más interesantes que han aparecido en escena a nivel internacional a lo largo de este año

Lynckia se puede probar online siempre que uses una versión moderna de Chrome o Firefox, sin necesidad de instalar nada manualmente (ni tener ningún tipo de plugin instalado).

Si quieres tener tu propio servidor Lynckia, su instalación para el caso de Ubuntu 12.04 es sencilla. Basta con ejecutar los scripts paso a paso. En mi caso, con Ubuntu 12.10, instalé las dependencias Node.js, Nodejs-dev y nmp desde el repositorio oficial de Ubuntu (sin usar el PPA de Chris Lea como indican las instrucciones) y pude compilar y probar la demo básica sin problemas. En la demo básica se lanza un servicio Lynckia en el puerto 3001 de tu máquina local. Abriendo esa url en Chrome, te pedirá permiso para acceder a la webcam y al micrófono. En cuanto concedas permisos, verás tu imagen en pantalla (y oirás lo que digas por el micro). Si abres otra pestaña en el navegador y repites el proceso, verás que debajo de la imagen original se abrirá otra más, a modo de videoconferencia (contigo mismo en esta demo, pero se entiende el objetivo, no? 😉

El albañil de la web

From Wikipedia, jugando con las palabras/enlaces: «Albañil […] también se refiere a aquel que se dedica a la reparación o reforma con materiales de obra. Antiguamente, al menos hasta el S. XIX, el oficio de albañilería era un oficio gremial. Para pertenecer a él, el candidato debía ser presentado por un miembro y ser aceptado formalmente como aprendiz. Una vez dentro del gremio podía conseguir distintos grados hasta llegar a maestro, que tenía una consideración social importante.»

Los albañiles de la web actual también deberían de pasar por un período de formación hasta conseguir el título de webmaster, tan en desuso hoy en en día…

Tenemos un problema a resolver: la siguiente web tiene un enlace para cambiar de idioma (de castellano a euskera o viceversa).

La cuestión es que al pinchar en el cambio de idioma, el navegador vuelve a la home de esa sección de la web, cambiando el contenido de la página por completo (cambia de idioma, pero nos lleva al «hall» de la web, en lugar de mantenernos donde estábamos)








Es decir, pasamos de estar aquí (navegando en español):

http://www.tic.ehu.es/p265-shintrct/es/contenidos/enlace/intrehutic_ldap_indice/es_indizea/ldap_indice.html

a estar aquí (navegando en euskera):

http://www.tic.ehu.es/p265-shintrhm/eu/

Podemos cambiar la URL original a mano, donde pone «es» lo sustituimos por «eu»… O bien, podemos hacer un pequeño script que lo haga por nosotros. Y si tenemos la ayuda de la consola de Chrome, mejor que mejor. Desde ese navegador, pulsamos el botón derecho sobre la página y seleccionamos «Inspect Element».

En la parte inferior izquierda, pulsamos sobre el botón que abre la consola. Veremos algo como lo siguiente:

En la parte inferior, he tecleado «wind» y el propio Chrome me sugiere que «window» es un objeto DOM válido, que puedo manipular vía Javascript. Estudiando un poco ese modelo DOM, y con la ayuda del propio navegador (autocompletamiento de nombres de objetos y propiedades), sabiendo que las teclas para movernos por una sugerencia de keyword son el tabulador y/o la «flecha derecha», llegaremos fácilmente a:

   window.location.href

Y si tras teclearlo pulsamos Enter:

Vemos que Chrome nos da el valor de esa propiedad href. Lo que nos interesa ahora es cambiar toda aparición de «es» por «eu» automágicamente 🙂 ¿Toda? Bueno, toda no, porque el .es del dominio no lo queremos cambiar. ¿Cómo obtener la parte de la URL a la derecha del dominio? Curioseando en el modelo DOM, vemos que es la propiedad window.location.pathname. Ahora, un find&replace y lo tenemos 🙂

¿Cómo lo añadimos ahora a la barra de bookmarks de Chrome para tenerlo siempre disponible? Botón derecho sobre la barra de bookmarks, «Add page..», y tecleamos lo que ves en la imagen de la izquierda (ojo, pulsa sobre la imagen o no verás un carajo)

Listo! Cuando pulsemos en el enlace especial Javascript que acabamos de crear (bookmarklet se llaman), cambiará la URL de la página, de «es» a «eu», con un sólo click.

El albañil se va a por el bocata, satisfecho del trabajo bien hecho 🙂