Skip to content

Instantly share code, notes, and snippets.

@machinescream
Last active June 2, 2020 11:52
Show Gist options
  • Save machinescream/6560b7e7e2166def56351c17b936a572 to your computer and use it in GitHub Desktop.
Save machinescream/6560b7e7e2166def56351c17b936a572 to your computer and use it in GitHub Desktop.
typedef ValueBuilder<T> = Widget Function(BuildContext context, T value);
typedef ErrorBuilder = Widget Function(BuildContext context, Object error);
class OsamBuilder<T> extends StatefulWidget {
final ValueStream<T> stream;
final ValueBuilder<T> builder;
final ErrorBuilder errorBuilder;
const OsamBuilder({Key key, @required this.stream, @required this.builder, this.errorBuilder}) : super(key: key);
@override
_OsamBuilderState<T> createState() => _OsamBuilderState<T>();
}
class _OsamBuilderState<T> extends State<OsamBuilder<T>> {
StreamSubscription<T> _dataSub;
T data;
Object error;
@override
Widget build(BuildContext context) {
return error != null ? widget.errorBuilder(context, error) : widget.builder(context, data ?? widget.stream.value);
}
@override
void didUpdateWidget(OsamBuilder<T> oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.stream.value != widget.stream.value) {
data = widget.stream.value;
_dataSub.cancel();
_subscribe();
}
}
void _subscribe() {
_dataSub = widget.stream.listen((event) {
error = null;
setState(() {
data = event;
});
});
_dataSub.onError((e) {
setState(() {
error = e;
});
});
}
@override
void initState() {
_subscribe();
super.initState();
}
@override
void dispose() {
_dataSub?.cancel();
super.dispose();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment