Cell Values
KalamCellValue is the typed wrapper around each individual cell value returned
in a Dart SDK query result or subscription event.
Instead of accessing raw dynamic values from positional rows, you use
typed accessor methods to extract values safely.
Quick Example
import 'package:kalam_link/kalam_link.dart';
final response = await client.query('SELECT id, name, score, avatar FROM users');
// Typed row maps: Map<String, KalamCellValue>
for (final row in response.rows) {
final id = row['id']?.asString(); // String?
final name = row['name']?.asString(); // String?
final score = row['score']?.asDouble(); // double?
final born = row['born_at']?.asDate(); // DateTime?
final url = row['avatar']?.asFileUrl(
'http://localhost:18080', 'default', 'users',
); // String?
print('$id $name $score $url');
}Creating a KalamCellValue
KalamCellValue.from(raw)
Wrap any raw dynamic value. Pass null for SQL NULL.
final cell = KalamCellValue.from(someRawValue);Accessing Typed Rows
QueryResult.rows
Returns List<Map<String, KalamCellValue>> — each row as a map with typed cell
values.
for (final row in result.rows) {
print(row['email']?.asString());
}Convenience on QueryResponse
final response = await client.query('SELECT * FROM orders');
final rows = response.rows; // List<Map<String, KalamCellValue>>Type Guards
| Getter | Type | Description |
|---|---|---|
cell.isNull | bool | true if this cell is SQL NULL |
cell.isString | bool | true if underlying value is a String |
cell.isNumber | bool | true if underlying value is a num |
cell.isBool | bool | true if underlying value is a bool |
cell.isObject | bool | true if underlying value is a Map |
cell.isArray | bool | true if underlying value is a List |
Typed Accessors
.asString(): String?
Returns the value as a String, or null for SQL NULL.
Handles {"Utf8": "..."} Rust-side string envelopes automatically.
final name = row['name']?.asString(); // "Alice".asInt(): int?
Returns the value as an int, or null.
Truncates doubles. Parses string-encoded integers.
final count = row['item_count']?.asInt(); // 7.asDouble(): double?
Returns the value as a double, or null.
Parses string-encoded floats.
final price = row['price']?.asDouble(); // 19.99.asBool(): bool?
Returns the value as a bool, or null.
Handles string-encoded booleans: "true", "false", "1", "0".
final active = row['is_active']?.asBool(); // true.asDate(): DateTime?
Returns the value as a DateTime, or null for SQL NULL / unparseable values.
Handles:
- Unix milliseconds (
int) - ISO 8601 strings (
"2024-01-01T00:00:00Z") - Numeric timestamp strings (
"1704067200000")
final created = row['created_at']?.asDate();
print(created?.toLocal());.asObject(): Map<String, dynamic>?
Returns the value as a Map<String, dynamic>, or null.
.asArray(): List<dynamic>?
Returns the value as a List<dynamic>, or null.
FILE Column Support
.asFile(): KalamFileRef?
Parse a FILE column value and return a KalamFileRef, or null.
final ref = row['attachment']?.asFile();
if (ref != null) {
print('${ref.name} (${ref.formatSize()})');
print(ref.isImage()); // true for image/* MIME types
}See the FILE Columns section for the full
KalamFileRef API.
.asFileUrl(baseUrl, namespace, table): String?
Convenience method — parse a FILE column and return the download URL.
final url = row['avatar']?.asFileUrl(
'http://localhost:18080',
'default',
'users',
);
// e.g. "http://localhost:18080/files/default/users/f0001/photo.png?id=..."Serialisation
.asJson(): dynamic
Returns the underlying raw JSON value. This is the preferred JSON accessor.
.toJson(): dynamic
Compatibility alias of .asJson().
Returns the underlying raw dynamic value. Use this when you need to pass the value to code that expects plain JSON data.
.toString(): String
Human-readable display:
- SQL NULL →
"NULL" String→ value as-is- everything else →
_raw.toString()
Using with Subscriptions
Subscription events (InsertEvent, UpdateEvent, DeleteEvent,
InitialDataBatch) expose rows as typed maps:
client.subscribe('SELECT * FROM orders').listen((event) {
switch (event) {
case InsertEvent():
final name = event.row['customer']?.asString();
final total = event.row['total']?.asDouble();
print('New order: $name \$$total');
case UpdateEvent():
final newName = event.row['customer']?.asString();
final oldName = event.oldRow?['customer']?.asString();
print('Order updated: $oldName → $newName');
case DeleteEvent():
print('Deleted: ${event.row['id']?.asInt()}');
case InitialDataBatch():
for (final row in event.rows) {
print(row['customer']?.asString());
}
default:
break;
}
});Available typed accessors on ChangeEvent subclasses
| Class | Property | Type |
|---|---|---|
InitialDataBatch | .rows | List<Map<String, KalamCellValue>> |
InsertEvent | .rows | List<Map<String, KalamCellValue>> |
InsertEvent | .row | Map<String, KalamCellValue> |
UpdateEvent | .rows | List<Map<String, KalamCellValue>> |
UpdateEvent | .row | Map<String, KalamCellValue> |
UpdateEvent | .oldRows | List<Map<String, KalamCellValue>> |
UpdateEvent | .oldRow | Map<String, KalamCellValue>? |
DeleteEvent | .oldRows | List<Map<String, KalamCellValue>> |
DeleteEvent | .row | Map<String, KalamCellValue> |
Full API Reference
| Member | Signature | Description |
|---|---|---|
KalamCellValue.from | (dynamic) → KalamCellValue | Wrap a raw value |
asJson | () → dynamic | Raw underlying value (preferred) |
toJson | () → dynamic | Raw underlying value |
isNull | bool getter | True if SQL NULL |
isString | bool getter | True if String |
isNumber | bool getter | True if num |
isBool | bool getter | True if bool |
isObject | bool getter | True if Map |
isArray | bool getter | True if List |
asString | () → String? | Value as String |
asInt | () → int? | Value as int |
asDouble | () → double? | Value as double |
asBool | () → bool? | Value as bool |
asDate | () → DateTime? | Value as DateTime |
asObject | () → Map<String, dynamic>? | Value as Map |
asArray | () → List<dynamic>? | Value as List |
asFile | () → KalamFileRef? | FILE column as KalamFileRef |
asFileUrl | (baseUrl, namespace, table) → String? | FILE column URL |
toString | () → String | Display string |