En el desarrollo web, según pasan los años, cada vez es más común el uso de frameworks javascript que nos facilitan la vida al programar. Uno de los más clásicos es JQuery, desde que salió siempre ha ofrecido utilidades de todo tipo, y aunque hoy en día existen más alternativas (como backbone, zepto, extjs, chibijs, o vanilla javascript), no cabe duda de que hoy por hoy es un referente y muchas de sus características han sido copiadas por otras muchas librerías o incluso por el propio javascript nativo.

Por ejemplo, una de las archiconocidas funciones es data(), que como nos indica la documentación oficial, su forma se utiliza de la siguiente manera:

  • $elemento.data(): Al usar sin parámetros, devuelve un objeto con todas las propiedades “data” que tenga dicho elemento.
  • $elemento.data(“propiedad”): Si se le pasa una cadena de texto, devuelve únicamente el valor de la propiedad con ese nombre.
  • $elemento.data(“propiedad”, valor): Si se le indican 2 parámetros, modifica el valor de la propiedad con ese nombre por el pasado en el 2º parámetro.

Pero, ¿de dónde obtiene data esas propiedades? Al ejecutar por primera vez la función en un elemento, se leerán todos sus atributos con el prefijo “data-“ y se generará un objeto JS cuyas propiedades son dichos atributos y sus valores. Así, si por ejemplo tenemos un elemento:

Al ejecutar $("#datos").data(), obtendremos el siguiente resultado:

{
    id: 5,
    color: "blue",
    active: true
}

Como se puede observar, no sólo obtiene las propiedades del DOM, sino que JQuery es capaz de parsearlas al tipo de dato apropiado (en el ejemplo, id como entero, color como cadena de texto y active como booleano).

No obstante, si en algún momento posterior a ejecutar esta función se cambiasen los atributos data-… en el Html no se actualizarían las propiedades del objeto data obtenido anteriormente. Es decir, estos atributos sólo se leen del DOM en su primera ejecución, pero a partir de ese momento JQuery los tiene almacenados en memoria y no vuelve a acceder a la vista para consultarlos o modificarlos.

Vamos a aclarar lo anteriormente explicado con un ejemplo: Supongamos que tenemos el anterior div, y además una función javascript que hiciese lo siguiente:

let dataId = $("#datos").data("id"); //5
setInterval(() => {
    $("#datos").attr("data-id",dataId ++);
    let currentDataIdValue = $("#datos").data("id");
}, 5000);

Es decir, cada 5 segundos se va a repintar el valor en el DOM de la propiedad data-id, incrementándolo en 1 cada ciclo, y luego recupera el valor de data en la variable currentDataIdValue.

A priori podríamos pensar que el valor de ésta variable sería distinto en cada ciclo, pero en realidad siempre nos devolvería 5, que es el que había al ejecutar la primera línea de código, y no el que esté reflejado en el Html al hacer la nueva asignación.

Aunque este ejemplo sea un caso bastante absurdo, y en nuestro código es probable que nunca hiciéramos algo así explícitamente, hay que tener en cuenta que muchas veces usamos plugins, scripts y frameworks de terceros que frecuentemente modifican el Html, inyectan elementos en el DOM y, en definitiva, realizan determinadas acciones en nuestra web que no siempre tenemos bajo control. Un caso podría ser si usásemos React. Este framework puede actualizar el HTML, refrescar componentes o partes de los mismos. Si al mismo tiempo mediante JQuery se está accediendo a propiedades data, es bastante probable que tarde o temprano nos encontremos en una situación como la que veíamos arriba.

Si en estos casos, nos interesase obtener el valor que hay en la vista, la función data no nos valdría, y habría que utilizar en su lugar otras alternativas. La más común, en este caso, sería attr, que en muchos aspectos es parecida a data, pero con algunos matices. Esta función, obtiene o modifica un atributo de un elemento del Html de la página de la siguiente forma:

  • $(“#datos”).attr(“data-id”): para obtener el valor de id.
  • $(“#datos”).attr(“data-color”): para obtener el valor de color.
  • $(“#datos”).attr(“data-active“): para obtener el valor de active.
  • $(“#datos”).attr(“data-id”, 7): para modificar el valor de id en el DOM.
  • $(“#datos”).attr(“data-active“, false): para modificar el valor de active en el DOM.

De esta forma, siempre recuperaríamos lo que hay reflejado en el Html, y así resolveríamos el conflicto.

Es importante recalcar que, para consultar valores, attr no es tan práctico como data, ya que no es capaz de parsear cada propiedad, devolviendo siempre una cadena de texto simple. En este caso, el id y active valdrían “5” y “true” respectivamente (como texto), y habría que hacer el trabajo de parseo manualmente para obtener los datos correctamente:

//Interpretar id
parseInt($("#datos").attr("data-id"));

//Interpretar active
$("#datos").attr("data-active") === "true"

En resumen, hemos visto que la función data de JQuery es muy útil para leer o modificar propiedades de los elementos del DOM, simplificando muchos casos al no tener que parsear cada tipo de dato o pudiendo obtener todas las propiedades del elemento en un objeto javascript con una sola llamada. No obstante, hay que tener en cuenta cómo funciona exactamente para conocer lo que hace y, sobre todo, lo que no hace. Asimismo, no podemos olvidar las excepciones que hemos mencionado antes, en donde las antiguas funciones como attr siguen siendo de ayuda.