# Retrieving data
There is two ways to retrieve data in heliosRX (and Firebase). Either as a
contiouns stream of data (subscribe
) or as one time event (fetch
).
In the first case data will continously be synced from Realtime Database.
In the second case data is only retrieved once and not synced any further.
sync | fetch (same syntax) | return type | |
---|---|---|---|
list (collection) | subscribeList | fetchList | GenericList |
filtered list | subscribeQuery | fetchQuery | GenericList |
node (document) | subscribeNode | fetchNode | GenericModel |
Both subscribe and fetch exists for nodes (or documents) and lists (or collections) of data. A special case of a list is a query. A query returns a list that has been filtered on the server according to certain criteria
While subscribeList
will return everything under the node tasks
:
/tasks/* --> $models.task.subscribeList()
subscribeNode
will only return one item:
/tasks/1 --> $models.task.subscribeNode(1)
fetchList
and subscribeList
, fetchQuery
and subscribeQuery
, fetchNode
and subscribeNode
have identical syntax and can be used interchangeably.
# Working with lists
One way to retrieve data is to define a new variable in the this
scope, during
the created
or mounted
lifecycle hooks:
data() {
return {}
},
created() {
let task_list = this.$models.task.subscribeList();
this.task_list = task_list;
this.task_list.$promise.then(() => {
// all tasks have been loaded
})
}
There is no need to define task_list
in data()
in order to make it reactive.
Return values of subscribeNode
/ subscribeList
/ subscribeQuery
are always reactive by themselves.
Another way is to return a GenericList
directly from a computed property:
computed: {
task_list() {
return this.$models.task.subscribeList();
}
}
In both cases task_list
will be available in the template:
<template>
<div v-if="task_list.$readyAll">
{{task_list.items}}
</div>
</template>
Some other useful properties you can use at this moment are:
Properties | Type | Description |
---|---|---|
.items | Object | Map from id to GenricModel (whereas id is: /example/<id> ) |
$readyAll | Boolean | Becomes true when all children are ready (downloaded) |
$readySome | Boolean | Becomes true when some children are ready (downloaded) |
$promise | Promise | A promise that will resolve, when $readyAll is true |
$numReady | Numeric | Number of children that are ready (downloaded) |
$numChildren | Numeric | Number of children |
$noaccess | Boolean | Did the user have permission |
$idList | Array | List of all child id's (whereas id is: /example/<id> ) |
GenericList's also provide some basic filter and sort functions, that return a array instead of an object. When data children are returned as array the id
can still be accessed through items[0].$id
.
Array helper functions | Returns GenericList with .items as array... |
---|---|
asArraySorted() | ... and sorted by the field sortidx |
asArraySortedBy(prop) | ... and sorted by <prop> |
asArrayFilteredBy(prop, value) | ... and filtered by <prop> == value |
itemsAsArrayWithoutDeleted() | ... but without deleted (field deleted is false) |
itemsAsArrayOnlyDeleted() | ... but only deleted |
Keep in mind theat these functions filter data locally. If you want to filter or order data on the server side considere using a query.
# Working with queries
The basic syntax for subscribeQuery
is the same as subscribeList
, but it takes
an additional argument query
which is an object:
let list = subscribeQuery(query); // Returs 'GenricList'
For example, if you want to get all tasks, that were created after timestamp 123456789
and limit the result to 100
children you could run the following query:
this.$models.task.subscribeQuery({
key: 'createdAt',
startAt: 123456789,
limit: 100
});
The properties of query
are mapped to native Firebase functions like this:
heliosRX | Firebase | Comment |
---|---|---|
no key | orderByKey() | No index needed. Key is always indexed |
{ key: '*' } | orderByValue() | [1] |
{ key: <key> } | orderByChild(<key>) | [2] |
{ value: <value> } | equalTo(<value>) | Depends on the order-by method chosen |
{ startAt: <start> } | startAt(<start>) | Read this on data ordering |
{ endAt: <end> } | endAt(<end>) | - |
{ limit: 100 } | limitToFirst(100) | - |
{ limit: -100 } | limitToLast(100) | - |
- | orderByPriority() | Not available |
- [1]
orderByValue
: Don't forget to addindexOn( [ '.value' ] )
- [2]
orderByChild
: Don't forget to addindexOn( [ <key> ] )
For more information please read the Firebase Docs:
# Working with single nodes
Nodes can be retrieved in the same way as lists, but an id
has to be provided:
{
props: {
taskId: { required: true },
},
computed() {
task() {
return this.$models.task.subscribeNode( this.taskId );
}
},
watch: {
'task.$ready' () {
// task is ready
}
},
}
Also a task instance can be created in one of the lifecycle hooks. This is especially useful if the component is responsible for writing data (like modals or forms):
data() {
return {
taskId: '1',
}
},
created() {
let task = this.$models.task.subscribeNode( this.taskId );
this.task = task.clone();
this.task_list.$promise.then(() => {
// task is ready
})
},
methods() {
this.task_list.write()
}
GenericModels
will have autogenerated props that wrap around the actual state ($state
).
For example the following schema
export default {
fields: {
title: { type: 'String', required: true },
createdAt: { type: 'ServerTimestamp' },
isDone: { type: 'Boolean' },
},
};
will produce the following auto-generated getters and setters:
Properties | Type | Description |
---|---|---|
title | String | Title (getter/setter for $state.title ) |
createdAt | moment | Converted to moment.js object |
isDone | Boolean | isDone (getter/setter for $state.isDone ) |
Some other useful properties from GenericModel
taht you can use are:
Properties | Type | Description |
---|---|---|
$id | String | id of the node (whereas id is: /example/<id> ) |
$idx | Numeric | A numeric index of the node if node is child element of a list |
$key | String | A unique key that can be used with v-for |
$ready | Boolean | Boolean that becomes true when node is ready (downloaded) |
$promise | Promise | A promise that will resolve, when $ready is true |
$state | Object | The raw state |
$dirty | Object | Object of fields that have been changed but not saved |
$invalid | Object | Object of fields that are invalid |
$isValid | Boolean | Whether the current state is valid (all props are valid) or not |
$exists | Boolean | Whether the node existed in the database or not |
Finally data can be written to the database with these methods:
Methods | Description |
---|---|
clone() | Required when data is changed locally. Creates a clone of the GenericModel. |
write() | Write dirty fields to database (usually requires clone() ) |
update() | Directly update fields in the database. Syntax:task.update(id, { isDone: true }) |