mainstream_extended 0.1.0 copy "mainstream_extended: ^0.1.0" to clipboard
mainstream_extended: ^0.1.0 copied to clipboard

<Fork of mainstream> A StreamBuilder alternative that provides builder and event callbacks including default visual handlers.

mainstream_extended #

This project is based on mainstream by Very Good Ventures. Thanks @verygood.ventures for your hard work.

A StreamBuilder alternative that provides builder and event callbacks including visual feedbacks.

See the Futuristic package for a similar API for working with Futures.

Problem #

StreamBuilder is one of the most powerful widgets in Flutter. Like AnimatedBuilder and ValueListenableBuilder, it can be used to selectively rebuild only parts of a widget, which is very efficient.

However StreamBuilder does not provide a way to receive callbacks for a Stream's data/error/done events. Often we may want to respond to those events by performing an action. For example, updating a Navigator. Doing this from inside the builder callback is unreliable because Flutter can call the build() method many times. So we need an additional stream listener. However this requires the boilerplate of creating a StatefulWidget and canceling our stream subscription. Also, if our stream is not a broadcast stream (meaning it supports multiple listeners), we might have to avoid using a StreamBuilder altogether.

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  StreamSubscription<FirebaseUser> _subscription;

  @override
  void initState() {
    super.initState();
    _subscription = FirebaseAuth.instance.onAuthStateChanged.listen((event) {
      Navigator.of(context).popUntil((route) => route.isFirst);
    });
  }

  @override
  void dispose() {
    _subscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<FirebaseUser>(
      stream: FirebaseAuth.instance.onAuthStateChanged,
      builder: (_context, snapshot) => snapshot.data.isAnonymous ? LoggedOut() : LoggedIn(),
    );
  }
}

Solution #

The MainStream widget uses the same underlying StreamBuilderBase used by StreamBuilder but also exposes additional onData/onError/onDone callbacks. These callbacks will not retriggered as the result of a widget rebuild. It also provides builder callbacks to build mutually exclusive busy/data/error widget states.

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MainStream<FirebaseUser>(
      stream: FirebaseAuth.instance.onAuthStateChanged,
      onData: (_) => Navigator.of(context).popUntil((r) => r.isFirst),
      dataBuilder: (_, data) => data.isAnonymous ? LoggedOut() : LoggedIn(),
    );
  }
}
  • Can be used in a StatelessWidget
  • Works with single-subscription and broadcast streams
  • Provides generic type safety for the data provided to callbacks. The type parameter <T> can be omitted if it can be inferred by the compiler.

Usage #

final myStream = Stream<int>.periodic(Duration(seconds: 1), (x) => x).take(5);

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MainStream<int>(
      stream: myStream,
      onData: (data) => print(data),
      onError: (error) => showDialog(...),
      onDone: () => print('Done!'),
      busyBuilder: (_) => CircularProgressIndicator(),
      dataBuilder: (_, data) => Text(data.toString()),
      errorBuilder: (_, error) => Text(error.toString()),
    );
  }

The stream parameter is required.

The optional busyBuilder displays a widget when the Stream is waiting for its first event. By default, it shows a centered CircularProgressIndicator.

The optional dataBuilder displays a widget when the Stream's last event it a succesful data payload. The resulting T value of the Stream<T> is provided as a parameter to the callback.

The optional errorBuilder displays a widget when the Stream last event is an error, typically an Error or Exception.

The optional emptyDataBuilder displays a widget when the Stream data is empty. Empty is calculated as null or T.isEmpty if T is a List or Map

The optional onData callback can be used to handle a successful data event by displaying an alert dialog or performing navigation, for example. This can be used in place of or together with the dataBuilder. This will not be retriggered as a result of a widget rebuild.

The optional onError callback can be used to handle an error event by displaying an alert dialog or sending to a logging provider, for example. It can be used in place of or together with the errorBuilder. This will not be retriggered as a result of a widget rebuild.

The optional onDone callback can be used to handle a Stream's done event. This will not be retriggered as a result of a widget rebuild.

The optional onEmptyData callback can be used to handle a Stream's empty event. Empty is calculated as null or T.isEmpty if T is a List or Map

15
likes
40
pub points
0%
popularity

Publisher

verified publisherarif.co

<Fork of mainstream> A StreamBuilder alternative that provides builder and event callbacks including default visual handlers.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on mainstream_extended