> For the complete documentation index, see [llms.txt](https://ng-girls.gitbook.io/todo-list-tutorial-spanish/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ng-girls.gitbook.io/todo-list-tutorial-spanish/local_storage.md).

# Almacenamiento local

## ¿Qué es Local Storage?

Local Storage, como su nombre inplica, es una herramienta para almacenar información localmente. Similar a las cookies, local storage almacena información en el computador del usuario, y con eso, nos permite a nosotros como desarrolladores, una manera fácil de acceder a la información para leer y escribir.

## Soporte de navegadores

Como local storage fue introducido a nosotros ocn HTML5, todos los navegadores que soporta en estándar HTML5 también soporta local storage. Básicamente es soportado por todos los navegadores modernos, incluyendo IE 8.

## ¡Queremos código!

Primero, para usar local storage, necesitamos acceder la instancia localStorage, la cual estea expuesta para nosotros globalmente. Esto significa que podemos llamar a los métodos disponibles con esta interface usando esta instancia.

Local storage almacena información en una forma de llave-valor, entonces la interfaz es bastante simple y tiene dos métodos principales: `getItem` y `setItem`

Un ejemplo de uso:

```
localStorage.setItem('name','Mor');

let name = localStorage.getItem('name'); 
alert('Hello '+name+'!');
```

Otro método muy util es `clear` y es usado para limpiar toda la información de local storage:

```
localStorage.clear();
```

Existen otros métodos maravillosos que están descritos [aquí](https://developer.mozilla.org/en-US/docs/Web/API/Storage).

## Hora de Angular (de vuelta a nuestra aplicación)

En la siguiente sección vamos a construir nuestro servicio de almacenamiento local, el cual luego será usado para almacenar nuestra lista de elementos. Como describimos anteriormente, vamos a generar el servicio usando Angular CLI:

```
ng g s todo-list-storage
```

El nuevo archivo `todo-list-storage.service.ts` debería ser creado con el siguiente código:

```
import { Injectable } from '@angular/core';

@Injectable()
export class TodoListStorageService {

  constructor() { }

}
```

**Si algo parece no-familiar/raro a ti, por favor, ve al** [**tutorial de Servicios**](https://github.com/ng-girls/todo-list-tutorial-spanish/tree/622095f217d7aec2a50c2024630b12e7aabb52ad/service.html) **para información mas detallada sobre servicios**.

Necesitamos proveer el servicio en nuestro `ngModule`. Abre `app.module.ts` y en la lista de `providers` añade la nueva clase:

```typescript
providers: [TodoListService, TodoListStorageService],
```

Asegúrate que la clase también esté importada en el archivo:

```typescript
import { TodoListStorageService } from './todo-list-storage.service';
```

Vamos a comenzar agregando una propiedad privada a nuestro servicio llamada `todoList` la cual contendrá los elementos.

```
private todoList;
```

Adicionalmente, vamos a añadir una constante que almacene el nombre de la llave con la que queremos usar nuestro local storage, agregala justo después d elos imports:

```
const storageName = 'aah_todo_list';
```

Ahora vamos a inicializar esta propiedad con datos, al obtenerlos de localStorage, entonces en el constructor agrega:

```typescript
constructor() {  
    this.todoList = JSON.parse(localStorage.getItem(storageName));  
}
```

¡Espera! ¿por qué `JSON.parse`? La respuesta es simple:

Como describimos anteriormente en este tutorial, local storage almacena información en forma llave-valor, lo que significa que los valores son almacenados como **cadenas**. Entonces si quieres tener un verdadero objeto para manejar, necesitas transformar la cadena en un objeto real.

Ahora comencemos a hacer cosas reales, pero primero vamos a declarar todos los métodos públicos que queremos exponer en este servicio, los cuale son **get, post, put** y **destroy**

Nuestro servicio debería verse similar a:

```typescript
import { Injectable } from '@angular/core';

const storageName = 'aah_todo_list';

@Injectable()
export class TodoListStorageService {

  private todoList;

  constructor() {
    this.todoList = JSON.parse(localStorage.getItem(storageName));
  }

  // get items
  get() {}

  // add a new item
  post(item) {}

  // update an item
  put(item, changes) {}

  // remove an item
  destroy(item) {}

}
```

Vamos a implementarlos uno por uno

### get

Este método simplemente retornarea el estado acutal de los elementos almacenados en el servicio:

```typescript
/**
   * get items
   * @returns {any[]}
   */
  get() {
    return [...this.todoList];
  }
```

Si no estás familiarizado con el operador `...` por favor ve a [esta documentación](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Spread_operator) para mas información.

### post

Este método será responsable por agregar nuevos elementos, y retornar una nueva lista.

Acepta un parámetro, `item` el cual será el elemento a agregar:

```typescript
/**
   * Add a new todo item
   * @param item
   * @returns {any[]}
   */
  post(item) {
    this.todoList.push(item);
    return this.get();
  }
```

Algo que debes haber notado es que nosotros solamente insertamos un elemento al arreglo. Pero ¿qué pasa con localStorage? ¡Necesitamos sincronizarlo con el nuevo arreglo!

Vamos a agregar un nuevo método **privado** a nuestro servicio, el cual será usado internamente para actualizar la lista almacenada:

```typescript
/**
   * Syncronize the local storage with the current list
   * @returns {any[]}
   */
  private update() {
    localStorage.setItem(storageName, JSON.stringify(this.todoList));

    return this.get();
  }
```

Vamos a explicar:

Aquí usamos el método `setItem`, el cual toma una llave (primer elemento) y un valor (segundo argumento) y lo almacena en `localStorage`. Después que actualizamos el valor, simplemente retornamos la nueva lista usando el método `get` que implementamos antes.

Ahora vamos a modificar nuestra función `post` para que use `update` y todo esté sincronizado en armonía:

```typescript
/**
   * Add a new todo item
   * @param item
   * @returns {any[]}
   */
  post(item) {
    this.todoList.push(item);
    return this.update();
  }
```

### put

Aquí nosotros queremos actualizar un elemento existente. Antes de eso, vamos a crear un método privado `findItemIndex` el cual simplemente retornará el índice de un elemento en la lista:

```typescript
/**
   * find the index of an item in the array
   * @param item
   * @returns {number}
   */
  private findItemIndex(item) {
    return this.todoList.indexOf(item);
  }
```

Ahora podemos usar `Object.assign` para actualizar el elemento existente:

```typescript
/**
   * Update an existing item
   * @param item
   * @param changes
   * @returns {any[]}
   */
  put(item, changes) {
    Object.assign(this.todoList[this.findItemIndex(item)], changes);
    return this.update();
  }
```

¿Qué está pasando aquí?

`Object.assign` toma el objeto destino (primer argument) y objetos recursos (todos los demás argumentos), y los copia al objeto destino. Si una propiedad existe en ambos, el recurso y el destino, este método reemplazará con la nueva. Aquí queremos actualizar un elemento en la lista, entonces primero necesitamos encontrar el índice en el arreglo, y luego aplicar los cambios a el. Al final, queremos sincronizar el almacenamiento local (`this.update`) y retornar la nueva lista.

### destroy

Este método eliminará un elemento de la lista y luego sincronizará con el almacenamiento local:

```typescript
/**
   * Remove an item from the list
   * @param item
   * @returns {any[]}
   */
  destroy(item) {
    this.todoList.splice(this.findItemIndex(item), 1);
    return this.update();
  }
```

El código anterior es muy simple. `splice(i, n)` elimina `n` elementos comenzando desde el índice `i`. En nuestro código, primero encontramos el índice el índice a eliminar, y luego lo elimina solo a el (por eso usamos 1 como segundo parámetro).

## Agregar alguna información por defecto

Vamos a asumir que queremos que nuestra lista de tareas siempre tenga información para comenzar. Entonces vamos a modificar nuestro servicio, al agregar en la sección de constantes (después de las importaciones):

```typescript
const defaultList = [
  { title: 'install NodeJS' },
  { title: 'install Angular CLI' },
  { title: 'create new app' },
  { title: 'serve app' },
  { title: 'develop app' },
  { title: 'deploy app' },
];
```

Y luego modificar nuestro constructor:

```typescript
constructor() {
    this.todoList = JSON.parse(localStorage.getItem(storageName)) || defaultList;
  }
```

El código anterior se asegura de que si no hay información definida en `localStorage`, nuestro servicio todavía tendrá información para devolver.

## ¡Casi terminamos!

Nuestor servicio está ahora listo para el trabajo. Pero espera, necesitamos proveerlo para poder usarlo.

Abre `app.module.ts` y luego agrega `TodoListStorageService` a la lista de `providers`.

¡Ahora verdaderamente podemos usar nuestro servicio!

Ahora para que nuestra aplicación use nuestro nuevo servicio, vamos a abrir `todo-list.service.ts` y modificarla.

Primero necesitamos importar el nuevo servicio:

```typescript
import { TodoListStorageService } from './todo-list-storage.service';
```

Luego, vamos a inyectarlo en el contructor, entonces vamos a tener una instancia para trabajar:

```typescript
constructor(private storage:TodoListStorageService) {
}
```

Esto nos deja usar `this.storage` en todo el servicio todo-list.

Vamos a modificar los métodos actuales:

**Antes**

```typescript
getTodoList() {
    return this.todoList;
}

addItem(item) {
    this.todoList.push(item);
}
```

**Después**

```typescript
getTodoList() {
    return this.storage.get();
}

addItem(item) {
    return this.storage.post(item);
}
```

Ahora vamos a realizar una última modificación. Abre `list-manager.component.ts`, y vamos a modificar el método `addItem` de esta manera:

```typescript
addItem(title:string) {
    this.todoList = this.todoListService.addItem({ item:title });
}
```

El cambio anterior nos asegura que cuando agreguemos un elemento, nuestra lista también se actualizará visualmente.

## Resumen

En este tutorial hemos aprendido que es `localStorage` y como usarlo. Vimos como `localStorage` es una herramienta genial y sencilla para almacenar información localmente en los dispositivos del usuario. También hemos implementado un nuevo servicio que utiliza `localStorage` para almacenar nuestros elementos `todo`, y actualizamos el resto de los componentes para soportar este nuevo servicio.

¡Disfruta el resto del tutorial!


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ng-girls.gitbook.io/todo-list-tutorial-spanish/local_storage.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
