Page updated Jan 16, 2024

DataStore events

DataStore periodically publishes state notifications onto Amplify's Hub. You can subscribe to the Hub to gain insight into the internal state of the DataStore. Events are published when:

  • Your device loses or regains network connectivity;
  • Data is synchronized with the Cloud;
  • There are new, pending changes that have not yet been synchronized.

The following DataStore events are defined:

networkStatus

Dispatched when DataStore starts and every time network status changes

HubPayload NetworkStatusEvent contains:

  • active (Bool): true if the DataStore is on a network that can connect the Cloud; false, otherwise

subscriptionsEstablished

Dispatched when DataStore has finished establishing its subscriptions to all models

HubPayload: N/A

syncQueriesStarted

Dispatched when DataStore is about to perform its initial sync queries

HubPayload syncQueriesStartedEvent contains:

  • models ([String]): an array of each model's name

modelSynced

Dispatched once for each model after the model instances have been synced from the cloud

HubPayload modelSyncedEvent contains:

  • model:
    • name (String): the name of the model that was synced
  • isFullSync (Bool): true if the model was synced with a "full" query to retrieve all models
  • isDeltaSync (Bool): true if the model was synced with a "delta" query to retrieve only changes since the last sync
  • new (Int): the number of new model instances added to the local store
  • updated (Int): the number of existing model instances updated in the local store
  • deleted (Int): the number of model instances deleted from the local store

syncQueriesReady

Dispatched when all models have been synced from the cloud

HubPayload: N/A

ready

Dispatched when DataStore as a whole is ready, at this point all data is available

HubPayload: N/A

outboxMutationEnqueued

Dispatched when a local change has been newly staged for synchronization with the Cloud

HubPayload outboxMutationEvent contains:

  • model:
    • name (String): the name of the model that is awaiting publication to the Cloud
  • element:
    • model (Model): the model instance that will be published

outboxMutationProcessed

Dispatched when a local change has finished synchronization with the Cloud and is updated locally

HubPayload outboxMutationEvent contains:

  • model:
    • name (String): the name of the model that has finished processing
  • element:
    • model (Model): the model instance that is processed
    • _version (Int): version of the model instance
    • _lastChangedAt (Int): last change time of model instance (unix time)
    • _deleted (Bool): true if the model instance has been deleted in Cloud

outboxStatus

Dispatched when:

  • the DataStore starts
  • each time a local mutation is enqueued into the outbox
  • each time a local mutation is finished processing

HubPayload OutboxStatusEvent contains:

  • isEmpty (Bool): a boolean value indicating that there are no local changes still pending upload to the Cloud

Usage

To see if the network status is active, you could set up the following listener:

// Create listener const listener = Hub.listen('datastore', async hubData => { const { event, data } = hubData.payload; if (event === 'networkStatus') { console.log(`User has a network connection: ${data.active}`) } }) // Remove listener listener();
1// Create listener
2const listener = Hub.listen('datastore', async hubData => {
3 const { event, data } = hubData.payload;
4 if (event === 'networkStatus') {
5 console.log(`User has a network connection: ${data.active}`)
6 }
7})
8
9// Remove listener
10listener();

To wait for the entire sync process to finish, you can listen for the ready event:

// Create listener const listener = Hub.listen("datastore", async hubData => { const { event, data } = hubData.payload; if (event === "ready") { // do something here once the data is synced from the cloud } }) // Remove listener listener();
1// Create listener
2const listener = Hub.listen("datastore", async hubData => {
3 const { event, data } = hubData.payload;
4 if (event === "ready") {
5 // do something here once the data is synced from the cloud
6 }
7})
8
9// Remove listener
10listener();

Here is an illustrative sample of events and payloads that happen when you start from an empty DataStore and start a sync. If you do:

await DataStore.clear(); await DataStore.start();
1await DataStore.clear();
2await DataStore.start();

This gets logged:

Event: {"channel":"datastore","payload":{"event":"storageSubscribed"},"source":"","patternInfo":[]} Event: {"channel":"datastore","payload":{"event":"networkStatus","data":{"active":true}},"source":"","patternInfo":[]} Event: {"channel":"datastore","payload":{"event":"outboxStatus","data":{"isEmpty":true}},"source":"","patternInfo":[]} Event: {"channel":"datastore","payload":{"event":"subscriptionsEstablished"},"source":"","patternInfo":[]} Event: {"channel":"datastore","payload":{"event":"syncQueriesStarted","data":{"models":["ModelX","ModelY","ModelLala"]}},"source":"","patternInfo":[]} Event: {"channel":"datastore","payload":{"event":"modelSynced","data":{"isFullSync":true,"isDeltaSync":false,"counts":{"new":5,"updated":0,"deleted":2}}},"source":"","patternInfo":[]} Event: {"channel":"datastore","payload":{"event":"modelSynced","data":{"isFullSync":true,"isDeltaSync":false,"counts":{"new":296,"updated":0,"deleted":2}}},"source":"","patternInfo":[]} Event: {"channel":"datastore","payload":{"event":"modelSynced","data":{"isFullSync":true,"isDeltaSync":false,"counts":{"new":8155,"updated":0,"deleted":0}}},"source":"","patternInfo":[]} Event: {"channel":"datastore","payload":{"event":"syncQueriesReady"},"source":"","patternInfo":[]} Event: {"channel":"datastore","payload":{"event":"ready"},"source":"","patternInfo":[]}
1Event: {"channel":"datastore","payload":{"event":"storageSubscribed"},"source":"","patternInfo":[]}
2
3Event: {"channel":"datastore","payload":{"event":"networkStatus","data":{"active":true}},"source":"","patternInfo":[]}
4
5Event: {"channel":"datastore","payload":{"event":"outboxStatus","data":{"isEmpty":true}},"source":"","patternInfo":[]}
6
7Event: {"channel":"datastore","payload":{"event":"subscriptionsEstablished"},"source":"","patternInfo":[]}
8
9Event: {"channel":"datastore","payload":{"event":"syncQueriesStarted","data":{"models":["ModelX","ModelY","ModelLala"]}},"source":"","patternInfo":[]}
10
11Event: {"channel":"datastore","payload":{"event":"modelSynced","data":{"isFullSync":true,"isDeltaSync":false,"counts":{"new":5,"updated":0,"deleted":2}}},"source":"","patternInfo":[]}
12
13Event: {"channel":"datastore","payload":{"event":"modelSynced","data":{"isFullSync":true,"isDeltaSync":false,"counts":{"new":296,"updated":0,"deleted":2}}},"source":"","patternInfo":[]}
14
15Event: {"channel":"datastore","payload":{"event":"modelSynced","data":{"isFullSync":true,"isDeltaSync":false,"counts":{"new":8155,"updated":0,"deleted":0}}},"source":"","patternInfo":[]}
16
17Event: {"channel":"datastore","payload":{"event":"syncQueriesReady"},"source":"","patternInfo":[]}
18
19Event: {"channel":"datastore","payload":{"event":"ready"},"source":"","patternInfo":[]}