Skip to Content
SDK & ClientDart / Flutter SDKCell Values (KalamCellValue)

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

GetterTypeDescription
cell.isNullbooltrue if this cell is SQL NULL
cell.isStringbooltrue if underlying value is a String
cell.isNumberbooltrue if underlying value is a num
cell.isBoolbooltrue if underlying value is a bool
cell.isObjectbooltrue if underlying value is a Map
cell.isArraybooltrue 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

ClassPropertyType
InitialDataBatch.rowsList<Map<String, KalamCellValue>>
InsertEvent.rowsList<Map<String, KalamCellValue>>
InsertEvent.rowMap<String, KalamCellValue>
UpdateEvent.rowsList<Map<String, KalamCellValue>>
UpdateEvent.rowMap<String, KalamCellValue>
UpdateEvent.oldRowsList<Map<String, KalamCellValue>>
UpdateEvent.oldRowMap<String, KalamCellValue>?
DeleteEvent.oldRowsList<Map<String, KalamCellValue>>
DeleteEvent.rowMap<String, KalamCellValue>

Full API Reference

MemberSignatureDescription
KalamCellValue.from(dynamic) → KalamCellValueWrap a raw value
asJson() → dynamicRaw underlying value (preferred)
toJson() → dynamicRaw underlying value
isNullbool getterTrue if SQL NULL
isStringbool getterTrue if String
isNumberbool getterTrue if num
isBoolbool getterTrue if bool
isObjectbool getterTrue if Map
isArraybool getterTrue 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() → StringDisplay string
Last updated on