Class: Record

Record


new Record(props, opts)

js-data's Record class. An instance of Record corresponds to an in-memory representation of a single row or document in a database, Firebase, localstorage, etc. Basically, a Record instance represents whatever kind of entity in your persistence layer that has a primary key.

import {Record} from 'js-data'
Method parameters:
Name Type Argument Description
props Object <optional>

The initial properties of the new Record instance.

opts Object <optional>

Configuration options.

Properties
Name Type Argument Default Description
noValidate Boolean <optional>
false

Whether to skip validation on the initial properties.

validateOnSet Boolean <optional>
true

Whether to enable setter validation on properties after the Record has been initialized.

Details
Since Source
3.0.0 Record.js, line 27
Examples

// Normally you would do: import {Record} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Record} = JSData
console.log('Using JSData v' + JSData.version.full)

// Instantiate a plain record
let record = new Record()
console.log('record: ' + JSON.stringify(record))

// You can supply properties on instantiation
record = new Record({ name: 'John' })
console.log('record: ' + JSON.stringify(record))

// Normally you would do: import {Mapper} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Mapper} = JSData
console.log('Using JSData v' + JSData.version.full)

// Instantiate a record that's associated with a Mapper:
const UserMapper = new Mapper({ name: 'user' })
const User = UserMapper.recordClass
const user = UserMapper.createRecord({ name: 'John' })
const user2 = new User({ name: 'Sally' })
console.log('user: ' + JSON.stringify(user))
console.log('user2: ' + JSON.stringify(user2))

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)

const store = new Container()
store.defineMapper('user')

// Instantiate a record that's associated with a store's Mapper
const user = store.createRecord('user', { name: 'John' })
console.log('user: ' + JSON.stringify(user))

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)

const store = new Container()
store.defineMapper('user', {
  schema: {
    properties: {
      name: { type: 'string' }
    }
  }
})

// Validate on instantiation
const user = store.createRecord('user', { name: 1234 })
console.log('user: ' + JSON.stringify(user))

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)

const store = new Container()
store.defineMapper('user', {
  schema: {
    properties: {
      name: { type: 'string' }
    }
  }
})

// Skip validation on instantiation
const user = store.createRecord('user', { name: 1234 }, { noValidate: true })
console.log('user: ' + JSON.stringify(user))
console.log('user.isValid(): ' + user.isValid())

Extends

This class extends the Component class.

Members


debug

Whether to enable debug-level logs for this component. Anything that extends Component inherits this option and the corresponding logging functionality.

Details
Type Since Default value Source
Boolean 3.0.0
false
Component.js, line 28
Inherited From:
Example

// Normally you would do: import {Component} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Component} = JSData
console.log('Using JSData v' + JSData.version.full)

const component = new Component()
component.log('debug', 'some message') // nothing gets logged
// Display debug logs:
component.debug = true
component.log('debug', 'other message') // this DOES get logged

Methods


<static> extend(props, classProps)

Create a subclass of this Record:

Method parameters:
Name Type Argument Default Description
props Object <optional>
{}

Properties to add to the prototype of the subclass.

Properties
Name Type Argument Description
constructor Object <optional>

Provide a custom constructor function to be used as the subclass itself.

classProps Object <optional>
{}

Static properties to add to the subclass.

Return value:
Type Description
Constructor

Subclass of this Record class.

Details
Since Source
3.0.0 Record.js, line 898
Example

// Normally you would do: import {Record} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Record} = JSData
console.log('Using JSData v' + JSData.version.full)

// Extend the class using ES2015 class syntax.
class CustomRecordClass extends Record {
  foo () { return 'bar' }
  static beep () { return 'boop' }
}
const customRecord = new CustomRecordClass()
console.log(customRecord.foo())
console.log(CustomRecordClass.beep())

// Extend the class using alternate method.
const OtherRecordClass = Record.extend({
  foo () { return 'bar' }
}, {
  beep () { return 'boop' }
})
const otherRecord = new OtherRecordClass()
console.log(otherRecord.foo())
console.log(OtherRecordClass.beep())

// Extend the class, providing a custom constructor.
function AnotherRecordClass () {
  Record.call(this)
  this.created_at = new Date().getTime()
}
Record.extend({
  constructor: AnotherRecordClass,
  foo () { return 'bar' }
}, {
  beep () { return 'boop' }
})
const anotherRecord = new AnotherRecordClass()
console.log(anotherRecord.created_at)
console.log(anotherRecord.foo())
console.log(AnotherRecordClass.beep())

_mapper()

Returns the Mapper paired with this record's class, if any.

Return value:
Type Description
Mapper

The Mapper paired with this record's class, if any.

Details
Since Source
3.0.0 Record.js, line 159

afterLoadRelations(relations, opts)

Lifecycle hook.

Method parameters:
Name Type Description
relations Array.<String>

The relations argument passed to Record#loadRelations.

opts Object

The opts argument passed to Record#loadRelations.

Details
Since Source
3.0.0 Record.js, line 174

beforeLoadRelations(relations, opts)

Lifecycle hook.

Method parameters:
Name Type Description
relations Array.<String>

The relations argument passed to Record#loadRelations.

opts Object

The opts argument passed to Record#loadRelations.

Details
Since Source
3.0.0 Record.js, line 184

changeHistory()

Return the change history of this record since it was instantiated or Record#commit was called.

Details
Since Source
3.0.0 Record.js, line 194

changes(opts)

Return changes to this record since it was instantiated or Record#commit was called.

Method parameters:
Name Type Argument Description
opts <optional>

Configuration options.

Properties
Name Type Argument Default Description
equalsFn Function <optional>
utils.deepEqual

Equality function.

ignore Array <optional>
[]

Array of strings or RegExp of fields to ignore.

Return value:
Type Description
Object

Object describing the changes to this record since it was instantiated or its Record#commit method was last called.

Details
Since Source
3.0.0 Record.js, line 205
Example

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)

const store = new Container()
store.defineMapper('user')
const user = store.createRecord('user')
console.log('user changes: ' + JSON.stringify(user.changes()))
user.name = 'John'
console.log('user changes: ' + JSON.stringify(user.changes()))

commit(opts)

Make the record's current in-memory state it's only state, with any previous property values being set to current values.

Method parameters:
Name Type Argument Description
opts Object <optional>

Configuration options. Passed to Record#toJSON.

Details
Since Source
3.0.0 Record.js, line 235
Example

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)

const store = new Container()
store.defineMapper('user')
const user = store.createRecord('user')
console.log('user hasChanges: ' + user.hasChanges())
user.name = 'John'
console.log('user hasChanges: ' + user.hasChanges())
user.commit()
console.log('user hasChanges: ' + user.hasChanges())

dbg(args)

Log the provided values at the "debug" level. Debug-level logs are only logged if Component#debug is true.

.dbg(...) is shorthand for .log('debug', ...).

Method parameters:
Name Type Argument Description
args * <optional>
<repeatable>

Values to log.

Details
Since Source
3.0.0 Component.js, line 124
Inherited From:

destroy(opts)

Call Mapper#destroy using this record's primary key.

Method parameters:
Name Type Argument Description
opts Object <optional>

Configuration options passed to Mapper#destroy.

Return value:
Type Description
Promise

The result of calling Mapper#destroy with the primary key of this record.

Details
Since Source
3.0.0 Record.js, line 264
Example
import {Container} from 'js-data'
import {RethinkDBAdapter} from 'js-data-rethinkdb'

const store = new Container()
store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })
store.defineMapper('user')
store.find('user', 1234).then((user) => {
  console.log(user.id) // 1234

  // Destroy this user from the database
  return user.destroy()
})

emit(event, args)

Trigger an event on this Component.

Method parameters:
Name Type Argument Description
event String

Name of event to emit.

args * <optional>
<repeatable>

Arguments to pass to any listeners.

Details
Since Source
3.0.0 Component.js, line 202
Inherited From:
Example

// import {Collection, DataStore} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Collection, DataStore} = JSData

const collection = new Collection()
collection.on('foo', function (msg) {
  console.log(msg)
})
collection.emit('foo', 'bar')

const store = new DataStore()
store.on('beep', function (msg) {
  console.log(msg)
})
store.emit('beep', 'boop')

get(key)

Return the value at the given path for this instance.

Method parameters:
Name Type Description
key String

Path of value to retrieve.

Return value:
Type Description
*

Value at path.

Details
Since Source
3.0.0 Record.js, line 293
Example

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)
const store = new Container()
store.defineMapper('user')

const user = store.createRecord('user', { name: 'Bob' })
console.log('user.get("name"): ' + user.get('name'))

hasChanges(opts)

Return whether this record has changed since it was instantiated or Record#commit was called.

Method parameters:
Name Type Argument Description
opts <optional>

Configuration options.

Properties
Name Type Argument Default Description
equalsFn Function <optional>
utils.deepEqual

Equality function.

ignore Array <optional>
[]

Array of strings or RegExp of fields to ignore.

Return value:
Type Description
Boolean

Return whether the record has changed since it was instantiated or since its Record#commit method was called.

Details
Since Source
3.0.0 Record.js, line 316
Example

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)
const store = new Container()
store.defineMapper('user')
const user = store.createRecord('user')
console.log('user hasChanges: ' + user.hasChanges())
user.name = 'John'
console.log('user hasChanges: ' + user.hasChanges())
user.commit()
console.log('user hasChanges: ' + user.hasChanges())

isNew()

Return whether the record is unsaved. Records that have primary keys are considered "saved". Records without primary keys are considered "unsaved".

Return value:
Type Description
Boolean

Whether the record is unsaved.

Details
Since Source
3.0.0 Record.js, line 347
Example

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)
const store = new Container()
store.defineMapper('user')
const user = store.createRecord('user', {
  id: 1234
})
const user2 = store.createRecord('user')
console.log('user isNew: ' + user.isNew()) // false
console.log('user2 isNew: ' + user2.isNew()) // true

isValid(opts)

Return whether the record in its current state passes validation.

Method parameters:
Name Type Argument Description
opts Object <optional>

Configuration options. Passed to Mapper#validate.

Return value:
Type Description
Boolean

Whether the record in its current state passes validation.

Details
Since Source
3.0.0 Record.js, line 373
Example

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)
const store = new Container()
store.defineMapper('user', {
  schema: {
    properties: {
      name: { type: 'string' }
    }
  }
})
const user = store.createRecord('user', {
  name: 1234
}, {
  noValidate: true // this allows us to put the record into an invalid state
})
console.log('user isValid: ' + user.isValid())
user.name = 'John'
console.log('user isValid: ' + user.isValid())

loadRelations(relations, opts)

Lazy load relations of this record, to be attached to the record once their loaded.

Method parameters:
Name Type Argument Description
relations Array.<String> <optional>

List of relations to load. Can use localField names or Mapper names to pick relations.

opts Object <optional>

Configuration options.

Return value:
Type Description
Promise

Resolves with the record, with the loaded relations now attached.

Details
Since Source
3.0.0 Record.js, line 438
Example
import {Container} from 'js-data'
import {RethinkDBAdapter} from 'js-data-rethinkdb'

const store = new Container()
store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })
store.defineMapper('user', {
  relations: {
    hasMany: {
      post: {
        localField: 'posts',
        foreignKey: 'user_id'
      }
    }
  }
})
store.defineMapper('post', {
  relations: {
    belongsTo: {
      user: {
        localField: 'user',
        foreignKey: 'user_id'
      }
    }
  }
})
store.find('user', 1234).then((user) => {
  console.log(user.id) // 1234

  // Load the user's post relations
  return user.loadRelations(['post'])
}).then((user) => {
  console.log(user.posts) // [{...}, {...}, ...]
})

log(level, args)

Log the provided values. By default sends values to console[level]. Debug-level logs are only logged if Component#debug is true.

Will attempt to use appropriate console methods if they are available.

Method parameters:
Name Type Argument Description
level String

Log level.

args * <optional>
<repeatable>

Values to log.

Details
Since Source
3.0.0 Component.js, line 134
Inherited From:

off(event, listener)

Remove an event listener from this Component. If no listener is provided, then all listeners for the specified event will be removed. If no event is specified then all listeners for all events will be removed.

Method parameters:
Name Type Argument Description
event String <optional>

Name of event to unsubsribe to.

listener Function <optional>

Listener to remove.

Details
Since Source
3.0.0 Component.js, line 180
Inherited From:
Examples
// Remove a particular listener for a particular event
collection.off('add', handler)
// Remove all listeners for a particular event
record.off('change')
// Remove all listeners to all events
store.off()

on(event, listener, ctx)

Register a new event listener on this Component.

Method parameters:
Name Type Argument Description
event String

Name of event to subsribe to.

listener Function

Listener function to handle the event.

ctx * <optional>

Optional content in which to invoke the listener.

Details
Since Source
3.0.0 Component.js, line 147
Inherited From:
Examples
// Listen for all "afterCreate" events in a DataStore
store.on('afterCreate', (mapperName, props, opts, result) => {
  console.log(mapperName) // "post"
  console.log(props.id) // undefined
  console.log(result.id) // 1234
})
store.create('post', { title: 'Modeling your data' }).then((post) => {
  console.log(post.id) // 1234
})
// Listen for the "add" event on a collection
collection.on('add', (records) => {
  console.log(records) // [...]
})
// Listen for "change" events on a record
post.on('change', (record, changes) => {
  console.log(changes) // { changed: { title: 'Modeling your data' } }
})
post.title = 'Modeling your data'

previous(key)

Return the properties with which this record was instantiated.

Method parameters:
Name Type Argument Description
key String <optional>

If specified, return just the initial value of the given key.

Return value:
Type Description
Object

The initial properties of this record.

Details
Since Source
3.0.0 Record.js, line 562
Example

// import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)
const store = new Container()
store.defineMapper('user')
const user = store.createRecord('user', {
  name: 'William'
})
console.log('user previous: ' + JSON.stringify(user.previous()))
user.name = 'Bob'
console.log('user previous: ' + JSON.stringify(user.previous()))
user.commit()
console.log('user previous: ' + JSON.stringify(user.previous()))

revert(opts)

Revert changes to this record back to the properties it had when it was instantiated.

Method parameters:
Name Type Argument Description
opts Object <optional>

Configuration options.

Properties
Name Type Argument Description
preserve Array.<String> <optional>

Array of strings or Regular Expressions denoting properties that should not be reverted.

Details
Since Source
3.0.0 Record.js, line 594
Example

// import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)
const store = new Container()
store.defineMapper('user')
const user = store.createRecord('user', {
  name: 'William'
})
console.log('user: ' + JSON.stringify(user))
user.name = 'Bob'
console.log('user: ' + JSON.stringify(user))
user.revert()
console.log('user: ' + JSON.stringify(user))

save(opts)

Delegates to Mapper#create or Mapper#update.

Method parameters:
Name Type Argument Description
opts Object <optional>

Configuration options. See Mapper#create and Mapper#update.

Properties
Name Type Argument Description
changesOnly Boolean <optional>

Equality function. Default uses ===.

equalsFn Function <optional>

Passed to Record#changes when opts.changesOnly is true.

ignore Array <optional>

Passed to Record#changes when opts.changesOnly is true.

Return value:
Type Description
Promise

The result of calling Mapper#create or Mapper#update.

Details
Since Source
3.0.0 Record.js, line 637
Example
import {Container} from 'js-data'
import {RethinkDBAdapter} from 'js-data-rethinkdb'

const store = new Container()
store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })
store.defineMapper('session')
const session = store.createRecord('session', { topic: 'Node.js' })

// Create a new record in the database
session.save().then(() => {
  console.log(session.id) // 1234

  session.skill_level = 'beginner'

  // Update the record in the database
  return session.save()
})

set(key, value, opts)

Set the value for a given key, or the values for the given keys if "key" is an object. Triggers change events on those properties that have track: true in Mapper#schema.

Method parameters:
Name Type Argument Description
key String | Object

Key to set or hash of key-value pairs to set.

value * <optional>

Value to set for the given key.

opts Object <optional>

Configuration options.

Properties
Name Type Argument Default Description
silent Boolean <optional>
false

Whether to trigger change events.

Fires:
Details
Since Source
3.0.0 Record.js, line 698
Example

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)
const store = new Container()
store.defineMapper('user')

const user = store.createRecord('user')
console.log('user: ' + JSON.stringify(user))

user.set('name', 'Bob')
console.log('user: ' + JSON.stringify(user))

user.set({ age: 30, role: 'admin' })
console.log('user: ' + JSON.stringify(user))

toJSON(opts)

Return a plain object representation of this record. If the class from which this record was created has a Mapper, then Mapper#toJSON will be called with this record instead.

Method parameters:
Name Type Argument Description
opts Object <optional>

Configuration options.

Properties
Name Type Argument Description
with Array.<String> <optional>

Array of relation names or relation fields to include in the representation. Only available as an option if the class from which this record was created has a Mapper and this record resides in an instance of DataStore.

Return value:
Type Description
Object

Plain object representation of this record.

Details
Since Source
3.0.0 Record.js, line 742
Example

// Normally you would do: import { Container } from 'js-data'
const JSData = require('js-data@3.0.0-rc.8')
const { Container } = JSData
console.log('Using JSData v' + JSData.version.full)
const store = new Container()
store.defineMapper('user', {
  schema: {
    properties: {
      name: { type: 'string' }
    }
  }
})

const user = store.createRecord('user', {
  name: 'John',
  $$hashKey: '1234'
})
console.log('user: ' + JSON.stringify(user.toJSON()))

unset(key, opts)

Unset the value for a given key. Triggers change events on those properties that have track: true in Mapper#schema.

Method parameters:
Name Type Argument Description
key String

Key to unset.

opts Object <optional>

Configuration options.

Properties
Name Type Argument Default Description
silent Boolean <optional>
false

Whether to trigger change events.

Details
Since Source
3.0.0 Record.js, line 789
Example

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)
const store = new Container()
store.defineMapper('user')

const user = store.createRecord('user', {
  name: 'John'
})
console.log('user: ' + JSON.stringify(user))

user.unset('name')
console.log('user: ' + JSON.stringify(user))

validate(opts)

Validate this record based on its current properties.

Method parameters:
Name Type Argument Description
opts Object <optional>

Configuration options. Passed to Mapper#validate.

Return value:
Type Description
*

Array of errors or undefined if no errors.

Details
Since Source
3.0.0 Record.js, line 819
Example

// Normally you would do: import {Container} from 'js-data'
const JSData = require('js-data@3.0.0-rc.4')
const {Container} = JSData
console.log('Using JSData v' + JSData.version.full)
const store = new Container()
store.defineMapper('user', {
  schema: {
    properties: {
      name: { type: 'string' }
    }
  }
})
const user = store.createRecord('user', {
  name: 1234
}, {
  noValidate: true // this allows us to put the record into an invalid state
})
console.log('user validation: ' + JSON.stringify(user.validate()))
user.name = 'John'
console.log('user validation: ' + user.validate())

Type Definitions


changeListener(The, The)

Callback signature for the Record#event:change event.

Method parameters:
Name Type Description
The Record

Record that changed.

The Object

changes.

Details
Type Since Source See
Function 3.0.0 Record.js, line 882
Example
function onChange (record, changes) {
  // do something
}
record.on('change', onChange)

Events


change

Fired when a record changes. Only works for records that have tracked fields. See Record~changeListener on how to listen for this event.