Stream.last callback never firing

Issue

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:

  1. Replace FutureBuilder with StreamBuilder and outTitle.last with outTitle.last.asStream();
  2. Call outTitle.last.then() outside widgets and from bloc constructor;
  3. Change signature of outTitle to ValueObservable and call last.wrapped;
  4. Change Rx’s BehaviorSubject to vanilla StreamController;
  5. Add to stream some values before building the view;

Nothing happens.
Just streams with StreamBuilders work well, but it is impossible to get the last value from last property.

Where can the problem lie?

Solution

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.

Answered By – Günter Zöchbauer

Answer Checked By – Timothy Miller (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.