I'm writing my Flutter app with a BLoC pattern. And what I want is pretty simple: show a TextField with the last value from a stream as an initial value.
There is the simple bloc:
class MyBloc {
BehaviorSubject<String> _titleController;
Stream<String> get outTitle => _titleController.stream;
Sink<String> get inTitle => _titleController.sink;
MyBloc(Model model) {
_titleController = BehaviorSubject(seedValue: model.title);
}
}
And the view with a FutureBuilder:
@override
Widget build(BuildContext context) {
var bloc = /* get the bloc from a widgets' hierarchy */
return FutureBuilder(
future: bloc.outTitle.last,
builder: (context, snapshot) {
return TextField(
controller: TextEditingController.fromValue(
TextEditingValue(text: snapshot.data ?? 'null')
),
);
}
);
}
The problem is that the FutureBuilder calls the builder only once with null data and "waiting" connection state.
What I tried:
FutureBuilder
with StreamBuilder
and outTitle.last
with outTitle.last.asStream()
;outTitle.last.then()
outside widgets and from bloc constructor;outTitle
to ValueObservable
and call last.wrapped
;BehaviorSubject
to vanilla StreamController
;Nothing happens.
Just streams with StreamBuilder
s work well, but it is impossible to get the last value from last
property.
Where can the problem lie?
last
is only emitted when the stream is closed. Otherwise the stream can't know what the last event is.
When you call
_titleController.close()
last
will emit a value.