# Persistence

ActiveJS [Units](https://docs.activejs.dev/activejs/fundamentals/units) can be made persistent by setting a configuration flag to `true`. By default, persistent Units use [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) for the persistence. You can change it to any storage API that implements [`Storage`](https://developer.mozilla.org/en-US/docs/Web/API/Storage) interface. e.g.: [`sessionStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage)

## Creating a persistent Unit

All that it takes to make a Unit persistent is a flag, and a unique `id`. The `id` is required to identify the Unit and its stored value.

```typescript
// this will throw an error, id is required
const preferencesUnit = new DictUnit({persistent: true});

// this will work
const preferencesUnit = new DictUnit({id: 'preferences', persistent: true});


// update Unit's value
preferencesUnit.set('side', 'dark');
// value in the LocalStorage would become {"side": "dark"}

// refresh the browser window

// check value
console.log(preferencesUnit.value()) // logs {"side": "dark"}
```

Voila! we're done. No manual saving, no manual retrieving.

## Initial value vs persisted value

When you provide an initial value to a persistent Unit, at first instance it gets saved to the persistent storage immediately, but when you refresh the browser window or open a new one, on the second instance the stored value takes precedence over the provided initial value.

```typescript
const preferencesUnit = new DictUnit({
    id: 'preferences', 
    persistent: true,
    initialValue: {earth: 'flat'}
});
// value in the LocalStorage would become {"earth": "flat"}

// set a new preference, which dispatches and saves a new value
preferencesUnit.set('earth', 'oblate ellipsoid');
// now LocalStorage has {"earth": "oblate ellipsoid"}

// now, refresh the browser window

// check value
console.log(preferencesUnit.value()) // logs {"earth": "oblate ellipsoid"}
// the initial value gets ignored
```

## Clearing the persisted value

Persisted value can be cleared in two ways, per Unit, or every Unit in a Storage instance.

* To clear the persisted value of a Unit, you can use `Unit.clearPersistedValue()`
* To clear all Units' persisted values from the default storage, you can use the global function `clearPersistentStorage()`.
* If you want to clear a particular storage you can pass it to the `clearPersistentStorage()` function.\
  **e.g**. `clearPersistentStorage(window.sessionStorage)`&#x20;

```typescript
// taking the Unit from above example, and starting from where we left
console.log(preferencesUnit.value()) // logs {"earth": "oblate ellipsoid"}

// clear the persisted value
preferencesUnit.clearPersistedValue();
// or clearPersistentStorage()
// or clearPersistentStorage(localStorage)

// check value
console.log(preferencesUnit.value()) // logs {"earth": "oblate ellipsoid"}
// because only the persisted value is removed, the Unit's value stays intact

// now, refresh the browser window

// check value
console.log(preferencesUnit.value()) // logs {"earth": "flat"}
// the initial value is used, because we cleared the persisted value
```

## Changing the persistence storage

All Units use the `localStorage` for persistence by default, but it can be changed to `sessionStorage` as well, and you can either change it globally or for a specific Unit.

### Changing storage for one Unit

```typescript
const unit = new DictUnit({
    id: 'session-token', 
    persistent: true, 
    
    // this is how we can change the storage for a Unit
    storage: window.sessionStorage
    // it overrides the default/global storage configuration
});
```

### Changing default storage for every Unit

You can change the default Storage API used by ActiveJS Units through the global [Configuration](https://docs.activejs.dev/activejs/guides/configuration).

```typescript
// set it in global configuration
Configuration.set({storage: window.sessionStorage})
// now all the persistent Units will use SessionStorage
// and the global clearPersistentStorage() will also operate on SessionStorage
```

{% hint style="danger" %}
Be advised that you should only change it once and that too before initializing any persistent Unit.\
Otherwise, some persistent Units will save their values in `LocalStorage` and try to restore it from `SessionStorage`. Also, the global function`clearPersistentStorage()` won't be able to clear persisted values from the other storage, you'll have to manually provide the non-current storage you want to clean up.
{% endhint %}

## Supported data types

It's advised to put only serializable data types in a persistent Unit, otherwise, the information will be lost in serialization done to save it in the LocalStorage. Non-serializable data types like Date, Map, Set, etc. are not supported.

All the data types that support `JSON.stringify` and `JSON.parse` can be used as values.

**Note:** `Date` object works with `JSON.stringify`, however it can't be parsed back to a `Date` object.\
When using the persisted value of the Unit, you'll only get a `string` representation of `Date`, not a `Date` `object`.
