Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter StreamBuilder Called Twice When Initialized

Is StreamBuilder always called twice? Once for initial data and then once for the input stream?

Initializing the following StreamBuilder shows that the build method is called twice. The second call is 0.4 seconds after the first one.

Stream: Build 1566239814897

Stream: Build 1566239815284

import 'dart:async';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:nocd/utils/bloc_provider.dart';

void main() =>
    runApp(BlocProvider<MyAppBloc>(bloc: MyAppBloc(), child: MyApp()));

class MyAppBloc extends BlocBase {
  String _page = window.defaultRouteName ?? "";

  /// Stream for [getPage].
  StreamController<String> pageController = StreamController<String>();

  /// Observable navigation route value.
  Stream get getPage => pageController.stream;

  MyAppBloc() {}

  @override
  void dispose() {
    pageController.close();
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final MyAppBloc myAppBloc = BlocProvider.of<MyAppBloc>(context);
    return StreamBuilder(
      stream: myAppBloc.getPage,
      initialData: "Build",
      builder: (context, snapshot) {
        print("Stream: " +
            snapshot.data +
            DateTime.now().millisecondsSinceEpoch.toString());
        return Container();
      },
    );
  }
}

Why is the StreamBuilder called twice?

like image 313
Ray Li Avatar asked Aug 19 '19 18:08

Ray Li


People also ask

What does StreamBuilder do in flutter?

StreamBuilder<T> class Null safety. Widget that builds itself based on the latest snapshot of interaction with a Stream.

Why do we use a StreamBuilder class in flutter?

If you need to build a widget dependent on the result of a Stream, you can utilize the StreamBuilder widget. You can make a Stream and pass it as the stream contention. Then, at that point, you need to pass an AsyncWidgetBuilder work that is utilized to construct a widget dependent on the snapshots of the Stream.

How many stream builder are in flutter?

There are two types of streams in Flutter: single subscription streams and broadcast streams. Single subscription streams are the default. They work well when you're only using a particular stream on one screen.


1 Answers

Streambuilder will be called 2 times, first for Initial and second for the stream. And data is only changed when state is ConnectionState.active. kinldy see the official doc example.

    StreamBuilder<int>(
  //stream:fire, // a Stream<int> or null
  builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
    if (snapshot.hasError) return Text('Error: ${snapshot.error}');
    switch (snapshot.connectionState) {
      case ConnectionState.none:
        return Text('Select lot');
      case ConnectionState.waiting:
        return Text('Awaiting bids...');
      case ConnectionState.active:
        return Text('\$${snapshot.data}');
      case ConnectionState.done:
        return Text('\$${snapshot.data} (closed)');
    }
    return null; // unreachable
  },
);

StreamBuilder documentation

The initial snapshot data can be controlled by specifying initialData. This should be used to ensure that the first frame has the expected value, as the builder will always be called before the stream listener has a chance to be processed.

initialData

Providing this value (presumably obtained synchronously somehow when the Stream was created) ensures that the first frame will show useful data. Otherwise, the first frame will be built with the value null, regardless of whether a value is available on the stream: since streams are asynchronous, no events from the stream can be obtained before the initial build.

like image 70
M.ArslanKhan Avatar answered Oct 13 '22 00:10

M.ArslanKhan