Skip to main content

Query Records

Query Records: fetches records of a cloud database class with filter/sort/limit, keeps results live, and outputs them as an array.

Query Records reads a class from the connected cloud database and exposes the matching records on items (an array of record objects), with count, firstItemId and isEmpty alongside. The query — class name, visual or JavaScript filter, sorting, limit and pagination — is configured in the node's parameters. Results are live by default: when a record elsewhere in the app is created, saved or deleted, the node re-checks it against the current query and updates items in place. fetched fires when a fetch completes, failure/error report problems.

When to use it

The starting point of every cloud-data list or lookup in browser logic. For writing data use Create/Save/Delete New Record nodes; for a single record by id use Model2/DbModel2; in cloud functions querying is available too (availableIn: cloud).

At a glance

CategoryCloud Services
Type nameDbCollection2
Available inbrowser, cloud
SSR compatibilitysafe
Provided bynoodl-runtime

Outputs

Values

NameTypeDefaultDescription
changedEventStringcreate, update, delete, init or resync
changedRecordObjectThe record the change was about. ⚠️ Null on a delete against Directus, which sends only the key — use Changed Record Id, which every backend fills
changedRecordIdStringThe id of the changed record, always a string — even where the backend's primary key is an integer
changedRecordsArrayEvery record in the change frame; some backends batch
countNumberHow many records are in Items, which Limit caps — turn on Fetch total count for the uncapped figure
firstItemIdStringId of the first matched record, for feeding a Record node without going through a repeater
isEmptyBooleanTrue when the query matched nothing, and also true before the first query has run
itemsArrayRecords the query matched, in the order Sort asks for; empty before the first query has run
realtimeStatusStringconnecting, subscribed, interrupted or stopped. Four states rather than a boolean, because "connecting for the first time" and "dropped and retrying" want different things on screen
subscribedBooleanTrue while the backend has confirmed the subscription and is delivering changes

Signals

NameTypeDefaultDescription
changedSignalAny of the three, and also the backend saying the view may be stale after a reconnect — the one to react to if you do not care which happened
createdSignalAnother client created a record in this collection
deletedSignalAnother client deleted a record from this collection
fetchedSignalFires once the query has returned and Items is up to date
updatedSignalAnother client updated a record in this collection

Failure outputs

NameTypeDefaultDescription
errorStringWhy the last query failed; empty until one does
failureSignalFires when the query could not be run, after the reason has been reported on the error channel
realtimeErrorObjectThe last realtime failure, with a code and whether retrying can help; null until one happens
realtimeFailureSignalFires when a subscription cannot connect, is rejected, or has been given up on

Dynamic ports

This node's port list changes at runtime (runtime-discovered, editor-adapter); the tables above may be incomplete for a given instance.

Filter/sort input ports are generated by the editor from the visual query (QueryRecordsAdapter) and the selected class schema.

Ports at runtime

All inputs are runtime-determined (runtime-discovered + editor-adapter): the class choice, filter values, sort keys and paging inputs are generated from the project's database schema and the visual filter you build in the editor — e.g. each 'value' placeholder in a filter becomes its own input port, and actions like fetch ('storageFetch') are registered on demand. A generator cannot enumerate them statically; an authoring tool should set collectionName and filter parameters, and may wire signals to fetch-related inputs which the runtime registers when used.

Patterns

  • items → Repeater items, with record properties delivered to the item component via Component Inputs: the canonical list page.
  • Event Receiver eventReceived → fetch input: re-run a query on demand from anywhere in the app.
  • Turn on Subscribe To Changes and wire Changed back into this node's own Do: the list stays current without polling, on every backend whose descriptor allows it — SSE on the built-in backend and PocketBase, a WebSocket on Directus.
  • Subscribed → a status indicator's visibility, so people can see when live updates are actually running rather than assuming.

Watch out for

  • Re-querying on a timer to feel 'live' — results already update from cloud events; explicit re-fetch is only needed when the server changed outside those events.
  • Treating Changed Record as the full record on a delete — delete events carry only primary keys, so it is null and only Changed Record Id is populated.
  • Polling with a Timer while Subscribe To Changes is available on this backend. Subscribe and re-fetch on Changed instead.
  • Assuming Subscribed distinguishes 'reconnecting' from 'never connected' — it does not. Read Realtime Status for that.

Examples

List page: Repeater fed by Query Records

The canonical data-list shape. Query Records (DbCollection2) fetches a database class and exposes the result on its items array output; the Repeater (For Each) consumes that array and instantiates its template component once per record. Each record's properties are delivered to the item component through Component Inputs whose names match the record's property names — the item component reads them like any other input. The Repeater and its item template component are separate components by design.

Decoupled communication with Send Event / Receive Event

Events carry a signal (and optional payload values) between components with no wire between them: every Receive Event listening on the same channelName fires when a Send Event on that channel sends. Here a toolbar button broadcasts 'RefreshRequested', and a separate component re-runs its data fetch when it receives the event. Use events when the sender must not know who reacts; for parent↔child data flow prefer Component Inputs/Outputs.

A list that keeps itself current, with Subscribe To Changes

A query is a snapshot — it only refreshes when Do fires. Turning on Subscribe To Changes closes that gap on the Query Records node itself: it holds a live subscription on the collection and fires Changed whenever any client creates, updates or deletes a record, so wiring ChangedDo keeps the list current without polling. Subscribed drives a small 'live' indicator so people can see when realtime updates are actually running, and Realtime Status says which of connecting/subscribed/interrupted it is in. Works on every backend that can push — SSE on the built-in backend and PocketBase, a WebSocket on Directus.

Records on a REST backend: query, create, update, delete

One Record family serves every backend. Query Records fetches on demand into items (re-trigger storageFetch to refresh — a query with realtime off does not re-query itself), Create/Update/Delete Record each act on a store signal and answer done (or failure) followed by completed, and Update and Delete take the record's modelId. After any write the query's storageFetch is re-triggered to refresh the list. No node here names a backend, so all five resolve the project's selected one; set the Backend input to point a single node somewhere else.

Reacting to what another user changed, without owning the query

Subscribe To Changes watches one class on the selected backend and fires signals when anything in it changes — no query, no list, no configuration beyond the class. Here it does the two things it is for at once: changed re-runs a Query Records node so the list on screen stays current, and created drives a 'new order' notice off changedRecord, which the subscription already carries so nothing has to be fetched to show it. subscribed drives a live indicator, so a dropped connection is visible rather than a screen that has quietly stopped updating. Against the built-in backend this needs no Backend setting at all: the picker defaults to the project's active backend and is not even shown when there is only one.

Repeater, Record, Create Record, Filter Records, Cloud Function, Subscribe To Changes

Generated

This page is generated from node-catalog-enriched.json. Do not edit it by hand — run npm run docs:nodes to regenerate, and fix the source enrichment instead.