domingo, 21 de abril de 2013

JSON (JavaScript Object Notation)

En JavaScript, habitualmente llamamos JSON a un objeto creado mediante la sintaxis:

var json = new Object()    o bien     var json = {}

Estos objetos son muy útiles para almacenar una estructura de datos como la que hice unos meses atrás en el que se guardaban los datos de un formulario en un array de dichos objetos.

Un JSON tiene la capacidad de crear atributos dentro de él e incluso crear estructuras dentro de sus atributos, creciendo de forma exponencial sus nodos, pero no lleva asociado ningún método para facilitar al programador algunos de los problemas más típicos que podemos encontrarnos.

Vamos a ver algunas técnicas útiles para dichos objetos que pueden facilitar la vida a muchos programadores:

Recorrer un JSON:

¿Cuantos atributos tiene mi JSON?
¿Qué nombres tienen los atributos?
¿Cómo puedo recorrerlo?

function recorrerJSON(json) {
    var i = 0;
    for (var attr in json) {
         console.log(attr);
         i++;
    }
    return "Hay "+ i + " atributos.";
}

Eliminar atributos del JSON

Para eliminar un atributo de un objeto JSON podría bastar en igualar el atributo a NULL. Pero el problema que tenemos es que el atributo sigue existiendo dentro del JSON, tomando su valor como NULL. Podemos solucionarlo creando otro JSON con la siguiente función:


function eliminarAttr(json,attr) {
  var temp = {};
  json[attr] = null;
for (var atr in json) {
if ((json[atr] != null)||(atr != attr)) {
temp[atr] = json[atr]
}
  }
return temp;
}

Fusionar varios JSON

Puede darse el caso que tengamos dos o más JSON en diferentes variables y queramos unificar toda la información en un único JSON. Vamos a crear una función para fusionar estos JSON. En caso de que exista el atributo en ambos JSON se machacará la información por la del segundo JSON.

function fusionarJSON(json1,json2) {
for (var attr in json2) {
json1[attr] = json2[attr];
}
return json1;
}

Acceder dinámicamente a los atributos del JSON (evitar uso del eval() )

Un JSON puede ser accedido a sus atributos principalmente de dos formas diferentes:

1) json.nombreDelAtributo
2) json["nombreDelAtributo"]

La forma más aconsejable es la segunda, accedes a los atributos del JSON como si de un Array se tratara. La ventaja de este método es que dentro de los corchetes le pasamos un String, que puede ser perfectamente una variable que con el primer método no podemos hacerlo.

Ejemplo:

Dentro de un bucle for, con un iterador " i " (variable) correspondiente a los atributos del json , accedemos a los campos de la siguiente manera:

1)
     eval("json."+i) --> Devuelve el valor del atributo "i" del JSON.

Esta práctica debe ser evitada, el uso de eval ha de evitarse tanto como se pueda ya que permite inyectar código a la página, abriendo puertas a posibles vulnerabilidades. Además de sobrecargar más el código y complicarlo más.

2)
json[i] --> Devuelve el valor del atributo "i" del JSON.

Sin hacer uso de ningún eval y simplificando notablemente el código obtenemos los mismos resultados que con el primer método.


Guardar/Recuperar JSON en localStorage de HTML5

HTML5 ofrece la posibilidad de guardar información de forma "permanente" al ordenador del usuario. Como si de una cookie se tratara pero con la ventaja de poder almacenar mucha más información que una cookie.
Una de las formas es usando el objeto localStorage que se puede acceder de la misma forma que un JSON:

Ejemplo:
 
   localStorage["ola"] = "5".
   Ahora si cerramos y abrimos el navegador y escribimos localStorage["ola"] nos devolvera nuestro 5.

La principal desventaja es que los valores de los atributos de la localStorage deben ser Strings. No podemos asignar-le un JSON entero. Debemos pasarlo a String previamente. podemos usar estas funciones para guardar y recuperar información:


function guardarJSON(json,nombre) { 
localStorage[nombre] = JSON.stringify(json); 
} 
function recuperarJSON(nombre) { 
return JSON.parse(localStorage[nombre]); 
}

Espero que estos pequeños Snippets sean de ayuda a alguien. Sería de agradecer algún comentario por si quedan dudas o mejoraríais las funciones, que de bien seguro se pueden mejorar. Pretendo que sean lo más simples posible para que cada uno se la haga a medida.

Un saludo.