How to avoid flutter StreamBuilder skipping data?

86 views Asked by At

It seems as if flutter StreamBuilder omits data if more than one data event occurs before the builder method gets executed.

I tried the following code which I expected to show "1;2;3;4;5;6;" etc. after pressing the button 3 times. (Shouldn't the builder method be called once for each ctrl.add() call?)

However, only every second ctrl.add() call reaches the builder method resulting in the output "2;4;6;".

Do I misunderstand the StreamBuilder behaviour? Or how can I fix the code so that multiple data can be sent "simultaneously"?

import 'dart:async';
import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  String _text = "";
  StreamController<int> ctrl = StreamController<int>();

  void _incrementCounter() {
    _counter++;
    ctrl.add(_counter);
    _counter++;
    ctrl.add(_counter);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder(
        stream: ctrl.stream,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            _text += "${snapshot.data};";
          }
          return Text(_text);
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        child: const Icon(Icons.add),
      ),
    );
  }
}
1

There are 1 answers

0
thmint On BEST ANSWER

OK, I found the answer in the flutter github issues pointing to the StreamBuilder documentation:

The builder is called at the discretion of the Flutter pipeline, and will thus receive a timing-dependent sub-sequence of the snapshots that represent the interaction with the stream.

So StreamBuilder just cannot be used if it is necessary to catch all data. :(

I got rid of StreamBuilder now and use a ChangeNotifier instead.