RxDart for the little ones… projects
how to start using ReactiveX in dart and Flutter

The other day, a friend of mine said something like “I’m writing a simple off-line application, I don’t need all these streams and reactivity.” I was even confused, and then I thought that some other programmers might have this misunderstanding.
Below, literally in 60 lines, I will show by a well-known example that reactivity
a) this is not about offline/online
b) it is very simple
c) very good for simplifying almost any code
The well-known example “Counter”, which is generated when creating a Flutter project, is a good starting point for demonstrating many practices.
So, it contains MyHomePage extends StatefulWidget, the _incrementCounter method for the increment command and setState for redrawing the entire widget hierarchy.
Add reactivity with the rxdart library and a few simple steps:
in “pubspec.yaml”
dependencies: … rxdart: 0.22.2
Make counter a class
class _Counter {
int count;_Counter(this.count) {
onCounterUpd.add(count);
}/// Make event
final onCounterUpd = BehaviorSubject<int>();/// Increment and fire event
Future incrementCounter() async {
onCounterUpd.add(++count);
}}final _counter = _Counter(10);
Make class Stateless
class MyHomeRxPage extends StatelessWidget {final title;/// Look - now class is constant!
const MyHomeRxPage({Key key, this.title}) : super(key: key);
Wrap receiver widget in the StreamBuilder and change call
StreamBuilder<int>(
initialData: _counter.onCounterUpd.value,
stream: _counter.onCounterUpd,
builder: (context, snapshot) {
return Text(
'${snapshot.data}',
style: Theme.of(context).textTheme.display1,
);
}),...floatingActionButton: FloatingActionButton(
onPressed: _counter.incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
That’s all. Look entire code:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:rxdart/rxdart.dart';
class _Counter {
int count;
_Counter(this.count) {
onCounterUpd.add(count);
}
/// Event
final onCounterUpd = BehaviorSubject<int>();
/// Change data and fire event
Future incrementCounter() async {
onCounterUpd.add(++count);
}
}
final _counter = _Counter(10);
///
class MyHomeRxPage extends StatelessWidget {
final title;
const MyHomeRxPage({Key key, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
StreamBuilder<int>(
initialData: _counter.onCounterUpd.value,
stream: _counter.onCounterUpd,
builder: (context, snapshot) {
return Text(
'${snapshot.data}',
style: Theme.of(context).textTheme.display1,
);
}),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _counter.incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}Now the code is reactive, concise, saved from unnecessary rebuildings, and easily extensible.
For example, if at the time of changing the counter you need to change the text of another widget, just do this:
StreamBuilder<int>(
initialData: _counter.onCounterUpd.value,
stream: _counter.onCounterUpd,
builder: (context, snapshot) {
return Text(
'You have pushed the button ${snapshot.data} times:',
);
}),
// Text(
// 'You have pushed the button this many times:',
// ),and voila!

Here the sample (branch `iter_0004_rxdart`)
Good luck with coding.
