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)
By creating/retrieving the record, the client will automatically receive all record updates made by other clients.
Properties
| Argument | Type | Description |
|---|---|---|
| name | String | The name of the record, as specified when calling client.record.getRecord( name ) |
| isReady | Boolean | True once the record has received its current data and emitted the 'ready' event |
| hasProvider | Boolean | True 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. |
| isDestroyed | Boolean | True 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)
| Argument | Type | Optional | Description |
|---|---|---|---|
| callback | Function | true | A 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?)
| Argument | Type | Optional | Description |
|---|---|---|---|
| path | String | true | A particular path within the JSON structure that should be set |
| value | Various | false | The value the record or path should be set to |
| callback | Function | true | Will 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.
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')
}
})
Forbidden paths
Since server v10.0.5, paths containing any of __proto__, constructor, or prototype are rejected by the server to prevent prototype-pollution attacks on the cached record state. Examples of paths that are now refused:
__proto__
constructor.prototype.toString
nested.__proto__.polluted
arr[0].constructor
When such a path is sent by a client (via set, setWithAck, setMulti, or any path-bearing record write), the server responds with INVALID_MESSAGE_DATA for that write and the record state is left unchanged. The same validation now also runs inside Valve permission rule evaluation, so a forbidden path will surface as a permission/validation failure rather than reaching cache or storage. If you need to store keys named like that, namespace them — e.g. meta.constructor becomes meta.userConstructor.
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...
}
})
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.