TinyBase

Relationships

A Relationships object lets you associate a Row in a one Table with the Id of a Row in another Table.

This is useful for creating parent-child relationships between the data in different Table objects, but it can also be used to model a linked list of Row objects in the same Table.

Create a Relationships object easily with the createRelationships function. From there, you can add new Relationship definitions (with the setRelationshipDefinition method), query their contents (with the getRemoteRowId method, the getLocalRowIds method, and the getLinkedRowIds method), and add listeners for when they change (with the addRemoteRowIdListener method, the addLocalRowIdsListener method, and the addLinkedRowIdsListener method).

This module defaults to creating relationships between Row objects by using one of their Cell values. However, far more complex relationships can be configured with a custom function.

Example

This example shows a very simple lifecycle of a Relationships object: from creation, to adding definitions (both local/remote table and linked list), getting their contents, and then registering and removing listeners for them.

const store = createStore()
  .setTable('pets', {
    fido: {species: 'dog', next: 'felix'},
    felix: {species: 'cat', next: 'cujo'},
    cujo: {species: 'dog'},
  })
  .setTable('species', {
    dog: {price: 5},
    cat: {price: 4},
  });

const relationships = createRelationships(store);
// A local/remote table relationship:
relationships.setRelationshipDefinition(
  'petSpecies', //  relationshipId
  'pets', //        localTableId to link from
  'species', //     remoteTableId to link to
  'species', //     cellId containing remote key
);
// A linked list relationship:
relationships.setRelationshipDefinition(
  'petSequence', // relationshipId
  'pets', //        localTableId to link from
  'pets', //        the same remoteTableId to link within
  'next', //        cellId containing link key
);

console.log(relationships.getRemoteRowId('petSpecies', 'fido'));
// -> 'dog'
console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
// -> ['fido', 'cujo']
console.log(relationships.getLinkedRowIds('petSequence', 'fido'));
// -> ['fido', 'felix', 'cujo']

const listenerId1 = relationships.addLocalRowIdsListener(
  'petSpecies',
  'dog',
  () => {
    console.log('petSpecies relationship (to dog) changed');
    console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
  },
);
const listenerId2 = relationships.addLinkedRowIdsListener(
  'petSequence',
  'fido',
  () => {
    console.log('petSequence linked list (from fido) changed');
    console.log(relationships.getLinkedRowIds('petSequence', 'fido'));
  },
);

store.setRow('pets', 'toto', {species: 'dog'});
// -> 'petSpecies relationship (to dog) changed'
// -> ['fido', 'cujo', 'toto']

store.setCell('pets', 'cujo', 'next', 'toto');
// -> 'petSequence linked list (from fido) changed'
// -> ['fido', 'felix', 'cujo', 'toto']

relationships.delListener(listenerId1);
relationships.delListener(listenerId2);
relationships.destroy();

See also

Relationships And Checkpoints guides

TinyDraw demo

Getter methods

This is the collection of getter methods within the Relationships interface. There are 8 getter methods in total.

Listener methods

This is the collection of listener methods within the Relationships interface. There are 4 listener methods in total.

Configuration methods

This is the collection of configuration methods within the Relationships interface. There are only two configuration methods, delRelationshipDefinition and setRelationshipDefinition.

Iterator methods

This is the collection of iterator methods within the Relationships interface. There is only one method, forEachRelationship.

Lifecycle methods

This is the collection of lifecycle methods within the Relationships interface. There is only one method, destroy.

Development methods

This is the collection of development methods within the Relationships interface. There is only one method, getListenerStats.