javascript

Almacenamiento en el navegador con JavaScript y localStorage

El almacenamiento de datos en el navegador usando JavaScript, además de las cookies, ya es una cosa que salió hace mucho tiempo. Sin embargo, muchas personas todavía no conocen sobre el tema o saben poco sobre el mismo.

Es por eso que en este post voy a explicar cómo trabajar con la API de localStorage en JavaScript para almacenar datos en el navegador del usuario, pero lo más importante es que estos datos van a persistir aunque el navegador se cierre o se actualice.

Nota: si quieres ver un ejemplo de localStorage mira este generador de UML.

Soporte de localStorage en los navegadores

Al momento de escribir este post, cualquier navegador decente soporta la tecnología localStorage en JavaScript, aunque para estar seguros veremos una forma de comprobar si el navegador lo soporta.

Recomendado: pouchDB

Hace mucho tiempo utilicé PouchDB para un proyecto que hice; pues esa librería de JavaScript es parecida a esto que veremos (aunque PouchDB es mejor y más robusta) ya que permite guardar datos de forma local.

Si quieres ver un ejemplo de PouchDB mira este ejemplo que hice.

Lecturas recomendadas

En los ejemplos uso funciones flecha y declaro algunas variables con let, mira los posts si quieres:

Arrow functions en JavaScript

Let, const y var en JavaScript

Detectar soporte de localStorage

Bueno, comencemos por ver si el navegador soporta localStorage. Como lo dije, cualquier navegador decente debe soportar esto. Mira la página de Can I Use para más información sobre el soporte.

No te preocupes por el código, más abajo lo vas a entender.

const funcionaLocalStorage = () => {
 // Si no existe el objeto, pues no hay soporte
 if(!window.localStorage) return false;
 // Ahora intentamos insertar y eliminar
 try{
  let id = "un_id_que_no_debe_repetirse";
  localStorage.setItem(id, "Soy un valor");
  localStorage.removeItem(id);
  return true;
 }catch(e){
  // Está lleno, está en modo privado, o cualquier cosa
  console.log(e);
  return false;
 }
};

Lo que estamos haciendo primero es ver si existe el objeto localStorage; pero que exista no significa que funcione, así que aparte de ello intentamos alojar y luego eliminar un elemento; si no se genera una excepción entonces significa que localStorage funciona como un encanto.

Cuidado con los tipos de datos

localStorage va a almacenar los datos como cadena, llamando al método toString del objeto que le pasemos. Por ello es que no debemos confiar en que va a respetar los tipos de dato; es decir, si le pasamos un entero, al recuperarlo lo tendremos como cadena.

Lo peor de esto es que si almacenamos un objeto, va a devolver la cadena literal [object Object] en lugar del objeto, hay que tener cuidado.

Más información sobre los lenguajes fuertemente y débilmente tipados aquí.

Entonces, ¿cómo almaceno más que cadenas con localStorage?

Qué malo eres, localStorage, ¿cómo es que no soportas más que cadenas? bueno, antes de comenzar a reclamar hay que recordar la existencia de JSON y la serialización de datos.

Ya que localStorage almacena cadenas, pues hay que pasarle un JSON en caso de que vayamos a guardar un objeto complejo. Si queremos números, siempre podemos cambiarlos de dato con parseInt o parseFloat

En resumen, si quieres almacenar objetos (cosa que es totalmente posible y común) codifícalos con JSON, y al recuperarlos decodifícalos.

No te voy a enseñar cómo trabajar con JSON porque ya he escrito un post sobre eso, el cual te recomiendo leer, pero en resumen usa JSON.stringify y JSON.parse.

Insertar elemento

Para insertar o añadir un elemento con localStorage existen dos maneras. La primera es declarar una propiedad del objeto localStorage y la segunda es llamar a setItem.

Vamos a centrarnos en la segunda, pues es más explícita. La sintaxis es:

localStorage.setItem("Clave", "Valor");

Así de simple es. Abajo muestro un ejemplo con varios tipos de datos, incluyendo a JSON.

localStorage.setItem("nombre", "Luis Cabrera Benito");
localStorage.setItem("edad", 123);
localStorage.setItem("recibirNotificaciones", true);
// Un objeto complejo
const mascota = {
  nombre: "Maggie",
  edad: 2,
  amigos: ["Meca", "Guayaba", "Snowball"]
};

localStorage.setItem("mascota", JSON.stringify(mascota));

¿Qué pasa si la clave ya existe?

No pasa nada, se actualiza el objeto.

Actualizar datos

Para actualizar los datos en localStorage, hay que llamar a setItem de nuevo y pasarle el dato completo que se va a almacenar.

Esto no funciona como los update de SQL en donde solamente actualizamos lo necesario, aquí tienes que pasar el dato completo y actualizado.

Saber si ya existe

Para saber si un valor ya existe con determinada clave, podemos usar hasOwnProperty o un simple if accediendo al valor.

if(localStorage.hasOwnProperty("edad")){
  // Perfecto, ya había un elemento con el id edad
}
// Otra forma:
if(localStorage.edad){
  // Ok, hay edad
}

// Todavía otra forma
if(localStorage["edad"]){
  // Ok hay edad :)
}

Cabe mencionar que es más recomendable usar hasOwnProperty, ya que JavaScript evalúa las cadenas vacías y el número 0 como false.

Eliminar datos

Para eliminar un dato de localStorage utiliza removeItem() y pásale la clave. La sintaxis es:

localStorage.removeItem("clave");

Obtener un valor

Si quieres recuperar un valor que guardaste anteriormente, llama a getItem pasándole la clave. Así:

let valorGuardado = localStorage.getItem("clave");

Recuerda que lo va a devolver como cadena y que debes convertirlo a determinado tipo si lo quieres usar. En el siguiente ejemplo muestro cómo recuperar y castear los objetos:

// Recuperar elementos

// No parsear porque lo queremos como cadena
let nombre = localStorage.getItem("nombre");
console.log("Te llamas ", nombre);
// convertir a entero
let edad = parseInt(localStorage.getItem("edad"));
console.log("Tu edad es: ", edad);
// Convertir a booleano
let recibirNotificaciones = Boolean(localStorage.getItem("recibirNotificaciones"));
console.log("¿Quiere recibir notificaciones?", recibirNotificaciones);
// Y a objeto
let mascotaDecodificada = JSON.parse(localStorage.getItem("mascota"));
console.log("La mascota es: ", mascotaDecodificada);

En el ejemplo estamos convirtiendo las cadenas a sus valores “reales” con todo y tipo de dato. Al imprimir los datos, se imprimen como son, no como cadenas:

Obteniendo valores de localStorage con JavaScript

Otra forma de obtener los valores

Ah, por cierto, para obtener un valor también podemos obtener la propiedad de localStorage. Por ejemplo, para obtener la edad usamos:

let edad = localStorage.edad;

En este caso no lo hacemos así porque no seríamos explícitos; desaconsejo usar esa manera.

Obtener todos los datos

Para obtener todos los registros que hemos guardado, sin saber la clave de los mismos, simplemente debemos acceder a todas las claves de localStorage.

Eso se logra gracias al fabuloso método llamado Object.keys recientemente introducido (no tiene nada que ver con localStorage, son cosas distintas) el cual devuelve un arreglo que tiene todas las claves, más tarde podemos iterarlo e ir obteniendo ese valor.

Veamos el ejemplo:

// Obtener todas las claves almacenadas
let claves = Object.keys(localStorage);
// Y por cada clave, ir obteniendo el valor de localStorage
claves.forEach(clave => {
  console.log("Tengo una clave: ", clave);
  let valor = localStorage.getItem(clave);
  // Castearlo o convertirlo depende de ti
  console.log("En esa clave el valor es:", valor);
});

Usamos un forEach que podría ser remplazado por un ciclo for normal. Lo importante es que usamos getItem para obtener el valor, y gracias a ello podemos obtener todos los elementos guardados.

Obtener todos los datos de localStorage

Conclusión

En este ejemplo guardamos valores nativos y simples, pero pensándolo bien y creando una bonita estructura podemos crear grandiosas cosas y sistemas complejos; eso sí, recuerda que estos datos se quedan en el navegador y que aunque el límite es grande, existe.

Por otro lado, si el usuario desinstala el navegador u obliga a que se borren los datos, nada podrás hacer. Justamente por eso es que se prefiere el uso de la arquitectura cliente-servidor.

 

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Ver comentarios

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

17 horas hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

1 semana hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

1 semana hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

1 semana hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

1 semana hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

1 semana hace

Esta web usa cookies.