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.
![](/assets/images/random-number-3b3d95ffd9a18cb845dc668c2da02b7f.png)
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.