TinyBase logoTinyBase

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.

import {createRelationships, createStore} from 'tinybase';
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
);
console.log(relationships.getRemoteRowId('petSpecies', 'fido'));
// -> 'dog'
console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
// -> ['fido', 'cujo']

// 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.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

Since

v1.0.0

Getter methods

Listener methods

Configuration methods

Iterator methods

Lifecycle methods

Development methods