Extension Methods
Jolt provides rich extension methods that make reactive programming more convenient. These extension methods allow you to easily manipulate reactive values and integrate with Flutter.
Readable Extension Methods
Extension methods for the Readable<T> interface, applicable to all read-only reactive values (such as Signal, Computed, etc.).
stream
Convert reactive values to broadcast streams.
final counter = Signal(0);
final stream = counter.stream;
stream.listen((value) => print('Counter: $value'));
// Output: "Counter: 0"
counter.value = 1; // Output: "Counter: 1"
counter.value = 2; // Output: "Counter: 2"listen
Create a stream subscription to listen for changes in reactive values.
final counter = Signal(0);
final subscription = counter.listen(
(value) => print('Counter: $value'),
immediately: true, // Immediately output current value
);
counter.value = 1; // Output: "Counter: 1"
subscription.cancel(); // Stop listeninguntil
Wait for a reactive value to satisfy a condition.
final count = Signal(0);
// Wait for count to reach 5
final future = count.until((value) => value >= 5);
count.value = 1; // Still waiting
count.value = 3; // Still waiting
count.value = 5; // Future completes, value is 5
final result = await future; // result is 5Async scenario example:
final isLoading = Signal(true);
// Wait for loading to complete
final data = await isLoading.until((value) => !value);
print('Loading complete');until() returns an Until<T>, so it can be awaited like a Future<T> and also cancelled if the condition will never be met:
final until = count.until((value) => value >= 5);
// await until;
until.cancel(); // Stops tracking and leaves the future pendingWritable Extension Methods
Extension methods for the Writable<T> interface, applicable to all writable reactive values (such as Signal, WritableComputed, etc.).
update
Update values using an update function based on the current value.
final count = Signal(5);
count.update((value) => value + 1); // count.value is now 6
count.update((value) => value * 2); // count.value is now 12This is equivalent to:
count.value = count.peek + 1;
count.value = count.peek * 2;readonly
Return a read-only view of a signal or writable computed value.
final counter = Signal(0);
final readonlyCounter = counter.readonly();
print(readonlyCounter.value); // OK
// readonlyCounter.value = 1; // Compile errorFor writable computed values:
final writableComputed = WritableComputed(getter, setter);
final readonlyComputed = writableComputed.readonly();
print(readonlyComputed.value); // OK
// readonlyComputed.value = 1; // Compile erroruntilWhen
Wait for a reactive value to equal a specific value.
final status = Signal('loading');
// Wait for status to become ready
final future = status.untilWhen('ready');
status.value = 'idle'; // Still waiting
status.value = 'ready'; // Future completes, value is 'ready'
final result = await future; // result is 'ready'untilChanged
Wait for a reactive value to change from its current value.
final status = Signal('idle');
final future = status.untilChanged();
status.value = 'loading'; // Future completes, value is 'loading'
final result = await future; // result is 'loading'call
Call a Readable as a function to get its value (creates reactive dependency).
final counter = Signal(0);
// These are equivalent:
final value1 = counter.value;
final value2 = counter(); // Using call extensionget
Get the value of a Readable (creates reactive dependency).
final counter = Signal(0);
// These are equivalent:
final value1 = counter.value;
final value2 = counter.get(); // Using get extensionderived
Create a computed value derived from this Readable.
final count = Signal(5);
final doubled = count.derived((value) => value * 2);
print(doubled.value); // 10
count.value = 6;
print(doubled.value); // 12Flutter Extension Methods
watch (Flutter only)
Create a widget that rebuilds when this Readable value changes. This extension is available in the jolt_flutter package.
import 'package:jolt_flutter/jolt_flutter.dart';
import 'package:jolt_flutter/extension.dart';
final counter = Signal(0);
// Use watch extension to create a reactive widget
counter.watch((value) => Text('Count: $value'))Important Notes
Performance Considerations: Extension methods create new reactive objects. For scenarios with frequent creation, consider using constructors directly.
Lifecycle: Reactive objects created through extension methods need manual lifecycle management. Remember to call
dispose()when done.Type Safety: Extension methods maintain complete type safety with compile-time type checking.
Stream Subscriptions: Subscriptions created using
listenorstreamneed manual cancellation to avoid memory leaks.