Skip to main content

Record

Records are one of deepstream's core features. A Record is an arbitrary JSON data structure that can be created, retrieved, updated, deleted and listened to. Records are created and retrieved using client.record.getRecord('name')

To learn more about how they are used, have a look at the Record Tutorial.

Creating records​

Records are created and retrieved using client.record.getRecord( 'name' );

const recordName = `user/${client.getUid()}` // "user/iqaphzxy-2o1pnsvcnbo"
const record = client.record.getRecord(recordName)
info

By creating/retrieving the record, the client will automatically receive all record updates made by other clients.

Properties​

ArgumentTypeDescription
nameStringThe name of the record, as specified when calling client.record.getRecord( name )
isReadyBooleanTrue once the record has received its current data and emitted the 'ready' event
hasProviderBooleanTrue once a listener accepts subscriptions to a record. Otherwise there are no active listeners. The 'hasProviderChanged' event is proving the information whenever the values has been changed.
isDestroyedBooleanTrue once the record has been discarded or deleted. The record would need to be retrieved again via `client.record.getRecord( name )

Events​

hasProviderChanged​

Emitted whenever the hasProvider property has been changed. Argument is the hasProvider property.

delete​

Emitted when the record was deleted, whether by this client or by another.

discard​

Emitted once the record was discarded.

error​

Emitted if the record encounters an error. The error message is passed to the event callback.

Methods​

whenReady(callback? | Promise)​

ArgumentTypeOptionalDescription
callbackFunctiontrueA function that should be invoked as soon as the record is ready.

Immediately executes the callback if the record is ready. Otherwise, it registers it as a callback for the ready event.

// Callback
record.whenReady(record => {
// data has now been loaded
})

// ES6
await record.whenReady()

set(path, value, callback?)​

ArgumentTypeOptionalDescription
pathStringtrueA particular path within the JSON structure that should be set
valueVariousfalseThe value the record or path should be set to
callbackFunctiontrueWill be called with the result of the write when using record write acknowledgements

Used to set the record's data and can be called with a value. A path and callback can optionally be included.

Including a callback will indicate that write acknowledgement to cache or storage is required and will slow down the operation.

info

After calling set, you still have to wait for the record to be ready before a get call will return the value assigned by set.

// Set the entire record's data
record.set({
personalData: {
firstname: 'Homer',
lastname: 'Simpson',
status: 'married'
},
children: ['Bart', 'Maggie', 'Lisa']
});

// Update only firstname
record.set('personalData.firstname', 'Marge')

// Set the entire record with write acknowledgement
record.set({
personalData: { ... },
children: [ ... ]
}, err => {
if (err) {
console.log('Record set with error:', err)
} else {
console.log('Record set without error')
}
});

// Update only a property with write acknowledgement
record.set('personalData.firstname', 'Homer', err => {
if (err) {
console.log('Record set with error:', err)
} else {
console.log('Record set without error')
}
})

Write error notification feature​

Starting with deepstream v6, there is slight change in the set logic that allows faster operations with write error notification. If writing to cache or storage fails, a RECORD_UPDATE_ERROR error message will be forwarded to the record instance that can be listened to and thus manage the write error from the client, without having to explicitely wait for the write acknowledgement. Before deepstream v6 if such error ocurred the client was not aware of it.

const record = client.record.getRecord('test')
// set record data without write ack
record.set({ data: 'ok' })
record.set('path', 5)

// record error listener
record.on('error', (e) => {
if (e === 'RECORD_UPDATE_ERROR') {
// write to database or cache failed
// handle it properly: retry or nuke the operation...
}
})
note

If RECORD_UPDATE_ERROR is emitted, all pending operations with write acknowledgement will receive the error message callback. This is due to the fact that a write error could potentially corrupt data and thus leave the record instance out of sync with the database.

setWithAck(path, value)​

ArgumentTypeOptionalDescription
pathStringtrueA particular path within the JSON structure that should be set
valueVariousfalseThe value the record or path should be set to

Used to set the record's data and can be called with a value. A path can optionally be included.

This function returns a promise that fulfills when writing to cache or storage completed thus slowing down the operation.

info

After awaiting setWithAck, the data is persisted so using get will retrieve the updated record.

// Set the entire record's data with write acknowledgement
await record.setWithAck({
personalData: {
firstname: 'Homer',
lastname: 'Simpson',
status: 'married'
},
children: ['Bart', 'Maggie', 'Lisa']
});

// Update only firstname with write acknowledgement
await record.setWithAck('personalData.firstname', 'Marge')

get(path)​

ArgumentTypeOptionalDescription
pathStringtrueA particular path within the JSON structure that should be retrieved.

Used to return the record's data but if called without an argument, will return all the data. get() can also be used to retrive a specific part by defining a path string. If the path can not be found, undefined will be returned.

record.get() // Returns entire object
record.get('children[1]') // 'Maggie'
record.get('personalData.firstname') // 'Homer'

subscribe(path, callback, triggerNow)​

ArgumentTypeOptionalDescription
pathStringtrueA path within the JSON structure that should be subscribed to.
callbackFunctionfalseA function that is called whenever the value changes and the data passed through.
triggerNowBooleantrueIf true, the callback function will be called immediately with the current value.

Registers a function will be called whenever the record's value changes. All of the record's data can be subscribed to by providing a callback function or when changes are performed to a specific path within the record.

Optional: Passing true will execute the callback immediately with the record's current value.

info

Subscribe is an operation done per record instance. Each time you call client.getRecord(name) you can subscribe and then unsubscribe to that specific record instance.

Listening to any changes on the record:

// Subscribe to any change of the record
function userDataChanged(data) {
// do stuff...
}
user.subscribe(userDataChanged)

Listening to changes on a specific path within the record:

// Only subscribe to the status of the user
function statusChanged( status ) {
if (status === 'married') {
// I want my childhood back!
}
}
user.subscribe('status', statusChanged, true)

unsubscribe(path, callback)​

ArgumentTypeOptionalDescription
pathStringtrueThe path that was previously used for subscribe.
callbackFunctionfalseThe previously registered callback function.

Removes a subscription previous made using record.subscribe(). Defining a path with unsubscribe removes that specific path, or with a callback, can remove it from generic subscriptions.

info

unsubscribe is entirely a client-side operation. To notify the server that the app would no longer interested in the record, and thus do not receive more data updates, use discard() instead.

Unsubscribe all callbacks registered with the path status:

user.unsubscribe('status')

Unsubscribe a specific callback registered for the path status:

user.unsubscribe('status', statusChanged)

Unsubscribe a specific callback registered for the record:

user.unsubscribe(userDataChanged)

Unsubscribe all callbacks not associated with a path:

user.unsubscribe()

discard()​

Removes all change listeners and notifies the server that client no longer wants updates for this record instance.

user.discard()

Make sure to avoid race conditions, there is a recordDiscardTimeout option that will define the number of milliseconds before actually executing the discard operation.

info

It is important to use this operation for record instances that are no longer needed in order to remove listeners.

delete()​

This permanently deletes the record on the server for all users.

user.delete()

Make sure to avoid race conditions, there is a recordDeleteTimeout option that will define the number of milliseconds before actually executing the delete operation.

info

Since deleting a record means that it no longer exists, the resulting action will be a forced discard to all clients with that record. Creating a record directly after deleting it without waiting for the delete event can end up in a race condition. Try to ensure the record has been deleted succesfully to avoid edge cases.

erase(path: string)​

Deletes a path from the record. Equivalent to doing record.set(path, undefined)

user.erase('name')

eraseWithAck(path: string, callback? | Promise)​

Deletes a path from the record and either takes a callback that will be called when the write has been done or returns a promise that will resolve when the write is done.