Random Stream
MobX provides a variety of reactive data structures to create your
reactive-state. You must have already seen examples of the Observable
,
ObservableSet
, ObservableMap
, ObservableList
, ObservableFuture
. To add
to this mix, we have the ObservableStream<T>
that takes a stream and makes it
reactive.
In this example, we will take a quick look at using the ObservableStream
by
observing a stream of random numbers.
See the complete code here.
The RandomStore​
Let's start out by creating a Store
to define our reactive state. The
RandomStore
defines a field named randomStream
, that is pumped with random
integers, every second. You can see the code below that defines the store:
part 'random_store.g.dart';
class RandomStore = _RandomStore with _$RandomStore;
abstract class _RandomStore with Store {
_RandomStore() {
_streamController = StreamController<int>();
_timer = Timer.periodic(const Duration(seconds: 1),
(_) => _streamController.add(_random.nextInt(100)));
randomStream = ObservableStream(_streamController.stream);
}
late final Timer _timer;
final _random = Random();
late final StreamController<int> _streamController;
late final ObservableStream<int?> randomStream;
// ignore: avoid_void_async
void dispose() async {
_timer.cancel();
await _streamController.close();
}
}
The ObservableStream<int>
wraps a Stream<int>
coming from the
StreamController<int>
. When the _timer
ticks, we are putting a new random
integer into the stream, now tracked by ObservableStream
. If there is a
reaction reading the randomStream.value
somewhere, it will surely re-execute
(react? :-)).
The reactive Observer​
Well, in this case, our reaction happens to be the Observer which will simply show the new random number on the screen.
The code is fairly straightforward. We are just reading the randomStream.value
and showing it inside the Text
component.
class RandomNumberExample extends StatefulWidget {
const RandomNumberExample();
_RandomNumberExampleState createState() => _RandomNumberExampleState();
}
class _RandomNumberExampleState extends State<RandomNumberExample> {
final RandomStore store = RandomStore();
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Random Number Generator'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Random number',
style: TextStyle(color: Colors.grey),
),
Observer(
builder: (_) {
final value = store.randomStream.value;
return Text(
'${value == null ? '---' : value}',
style: TextStyle(fontSize: 96),
);
},
),
],
),
));
void dispose() {
store.dispose();
}
}
See the complete code here.