In this post, we are going to learn how we can keep our application state in sync when a user has multiple tabs open. We are going to make this happen by using the Web Storage API and Akita. Basic knowledge of Akita is needed.
Create Contacts Page
For our demo, we will create a contacts page, that allows our users to add, edit and remove a contact.
ng add @datorama/akita
ng g af contacts
The above commands add Akita to our project and scaffold the files we need, entity store, entity query, model and service.
Now, let's add Akita's persistState
:
// main.ts
import { persistState } from '@datorama/akita';
persistState({
key: 'yourKey',
include: ['contacts']
});
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch(err => console.log(err));
From the docs: The persistState
function gives you the ability to persist some of the app’s state, by saving it to localStorage/sessionStorage or anything that implements the StorageEngine API, and restore it after a refresh.
Now, the only thing we need to do is to listen to the window.storage
event which fires when localStorage
has been modified in the context of another document. When it emits, we filter the key
we are interested in and call the snapshotManager.setStoresSnapshot
method with the new value.
import { untilDestroyed } from 'ngx-take-until-destroyed';
import { fromEvent } from 'rxjs';
import { snapshotManager } from '@datorama/akita';
class AppComponent {
ngOnInit() {
fromEvent<StorageEvent>(window, 'storage').pipe(
filter(event => event.key === 'yourKey')
untilDestroyed(this)
).subscribe(event => {
snapshotManager.setStoresSnapshot(event.newValue, { skipStorageUpdate: true });
});
}
}
The setStoresSnapshot
method takes the application state object which looks like:
{
"storeName": state,
"storeName": state
}
and updates each store with the given value.
Try it. Open your application in two tabs, change the store's value in one of them and see it reflected in the second one.
The inspiration for the article came from the ngrx version of it.
Top comments (0)