Reading From Stores
This guide shows you how to read data from a Store
.
While we're here, notice how the the createStore
function and setter methods return the Store
again, so we can easily instantiate it by chaining methods together:
import {createStore} from 'tinybase';
const store = createStore()
.setValues({employees: 3, open: true})
.setTables({
pets: {fido: {species: 'dog'}},
species: {dog: {price: 5}},
});
To get the data out again, according to the level of the hierarchy that you want to get data for, you can use the getValues
method, the getValue
method, the getTables
method, the getTable
method, the getRow
method, or the getCell
method.
By now, this should be starting to look intuitive. (I hope so! If not, let me know!)
console.log(store.getValues());
// -> {employees: 3, open: true}
console.log(store.getValue('employees'));
// -> 3
console.log(store.getTables());
// -> {pets: {fido: {species: 'dog'}}, species: {dog: {price: 5}}}
console.log(store.getTable('pets'));
// -> {fido: {species: 'dog'}}
console.log(store.getRow('pets', 'fido'));
// -> {species: 'dog'}
console.log(store.getCell('pets', 'fido', 'species'));
// -> 'dog'
It is worth noting that the return types of these methods are by value, not by reference. So if you manipulate the returned object, the Store
is not updated:
const fido = store.getRow('pets', 'fido');
fido.color = 'brown';
console.log(fido);
// -> {species: 'dog', color: 'brown'}
console.log(store.getRow('pets', 'fido'));
// -> {species: 'dog'}
Handling Non-Existent Data
The hasValue
method, the hasTable
method, the hasRow
method, and the hasCell
method can be used to see whether a given object exists, without having to read it:
console.log(store.hasValue('website'));
// -> false
console.log(store.hasTable('customers'));
// -> false
console.log(store.hasRow('pets', 'fido'));
// -> true
When you try to access something that doesn't exist, you'll receive an undefined
value for a Value
or Cell
, or an empty object:
console.log(store.getValue('website'));
// -> undefined
console.log(store.getTable('customers'));
// -> {}
console.log(store.getRow('pets', 'felix'));
// -> {}
console.log(store.getCell('pets', 'fido', 'color'));
// -> undefined
Enumerating Ids
A Store
contains Value
and Table
objects, keyed by Id
. A Table
contains Row
objects, keyed by Id
. And a Row
contains Cell
objects, keyed by Id
.
You can enumerate the Id
keys for each with the getValueIds
method, the getTableIds
method, the getRowIds
method, or the getCellIds
method - each of which return arrays:
console.log(store.getValueIds());
// -> ['employees', 'open']
console.log(store.getTableIds());
// -> ['pets', 'species']
console.log(store.getRowIds('pets'));
// -> ['fido']
console.log(store.getCellIds('pets', 'fido'));
// -> ['species']
There is also the getSortedRowIds
method that lets you get the Ids
sorted by a specific Cell
Id
, and the getTableCellIds
method that lets you get all the Ids
used across a whole Table
.
Again, the return types of these methods are by value, not by reference. So if you manipulate the returned array, the Store
is not updated:
const tableIds = store.getTableIds();
tableIds.pop();
console.log(tableIds);
// -> ['pets']
console.log(store.getTableIds());
// -> ['pets', 'species']
Finally, the forEachValue
method, the forEachTable
method, the forEachRow
method, and the forEachCell
method each provide a convenient way to iterate over these objects and their children in turn:
store.forEachTable((tableId, forEachRow) => {
console.log(tableId);
forEachRow((rowId) => console.log(`- ${rowId}`));
});
// -> 'pets'
// -> '- fido'
// -> 'species'
// -> '- dog'
Summary
So far, this should seem relatively straightforward. For more information on all of these methods, you'll find a lot more in the Store
documentation.
The reactive TinyBase magic starts to happen when we register listeners on the Store
so we don't have to keep explicitly fetching data.
For that, we proceed to the Listening To Stores guide.