Skip to main content

Records and Navigation

An FdcDataSet contains records and exposes one current position within the active visible view. Grids, editors, and application logic observe that shared current record.

Load records

For a local dataset:

await dataSet.loadRows(<Map<String, Object?>>[
<String, Object?>{'id': 1, 'name': 'Northstar Analytics'},
<String, Object?>{'id': 2, 'name': 'BluePeak Logistics'},
<String, Object?>{'id': 3, 'name': 'Vertex Manufacturing'},
]);

For an adapter-backed dataset:

await dataSet.open();

After loading, the dataset enters browse state and exposes the visible records through its cursor model.

Current position

The public position model is 1-based:

print(dataSet.recordNumber); // 1 for the first visible record
print(dataSet.recordCount); // number of visible records

Use isEmpty when the intent is simply to check whether the active view contains records:

if (dataSet.isEmpty) {
return const Text('No records');
}
dataSet.first();
dataSet.next();
dataSet.prior();
dataSet.last();

Move directly to a visible record number:

dataSet.moveToRecord(25);

moveToRecord uses the public 1-based range 1..recordCount.

EOF loops

The dataset supports classic cursor iteration:

dataSet.first();

while (!dataSet.eof) {
print(dataSet['name']);
dataSet.next();
}

Calling next() from the last visible record reaches the logical end boundary while keeping the cursor on the last real record. This allows the last row to be processed exactly once by the loop above.

The active view matters

recordCount and recordNumber refer to the active visible view, not necessarily every raw record held internally.

The view can be affected by:

  • filtering;
  • sorting;
  • searching;
  • paging;
  • selection-oriented query features;
  • master-detail constraints.

Application code should navigate through the dataset API instead of assuming that a raw storage index is equivalent to a visible row number.

Read the current record through fields

For normal application code, access current values through the dataset:

final id = dataSet.fieldByName('id').asInteger;
final name = dataSet.fieldByName('name').asString;

or with concise raw access:

final name = dataSet['name'];

This keeps reads aligned with the current cursor and active edit buffer.

Record identity and key fields

Dataset records have an internal identity used for correlation and change tracking. Persistent storage identity is described by fields marked isKey: true.

FdcIntegerField(
name: 'customer_id',
isKey: true,
)

Multiple key fields form a composite storage identity in declaration order.

Keys are particularly important for adapter-backed updates and deletes because adapters need to identify the storage row affected by a dataset change.

For application workflows that need lifecycle hooks around record movement, FdcDataSet provides beforeScroll and afterScroll callbacks.

Use them for behavior tied to record navigation, not for keeping duplicate widget state synchronized. Bound FDC controls already listen to the dataset directly.

Next: DataSet State