flutter_data_stream_builder 0.0.6

  • Readme
  • Changelog
  • Example
  • Installing
  • 66

DataStreamBuilder #

Pub

A pragmatic StreamBuilder with sensible defaults.

😩 The problem with StreamBuilder #

StreamBuilder is an essential tool to work with BLoCs or generally any stream.

But with enough streams in our codebase, a lot of boilerplate is introduced. Code gets repetitive and can't be easily reused:

StreamBuilder(
  stream: bloc.stock,
  builder: (context, AsyncSnapshot<Stock> snapshot) {
    if (snapshot.hasData) {
      return Text(snapshot.data.stock.toString());
    } else if (snapshot.hasError) {
      return Text(snapshot.error.toString());
    }
    return Center(child: CircularProgressIndicator());
  },
),

DataStreamBuilder aims to fix these issues for the common usecase:

DataStreamBuilder(
  stream: bloc.stock,
  builder: (context, Stock stock) => Text(stock.local.toString())
),

This library provides default builders for the loading and error states (can be supplied as loadingBuilder and errorBuilder), and only calls builder when data is present.

Depending on your current StreamBuilders this could be a drop-in replacement. In any case, it's super easy to migrate to DataStreamBuilder.

Note: if you need fine-grained control over ConnectionStates to the underlying computation, just use StreamBuilder.

👩🏾‍💻 Usage #

Using defaults for loading and error states:

DataStreamBuilder<List<Post>>(
  stream: Repository.of<Post>().findAll(),
  builder: (context, List<Post> posts) => ListView(
    children: posts.map((post) => ListTile(title: Text(post.body))).toList(),
  )
)

In case you are wondering, these are the defaults:

Default loading widget:

(context) => Center(child: CircularProgressIndicator());

Default error widget:

(context, dynamic error) {
  error = error is Exception ? error.toString() : 'Error: $error';
  return Center(child: Text(
      error,
      textDirection: TextDirection.ltr,
      style: TextStyle(backgroundColor: Colors.red, color: Colors.white),
    )
  );
};

Another example with custom loading and error widgets:

DataStreamBuilder<List<Post>>(
  stream: Repository.of<Post>().findAll(),
  loadingBuilder: (context) => Center(child: Text('Loading posts...')),
  errorBuilder: (context, error) => PostErrorView(error),
  builder: (context, List<Post> posts) => ListView(
    children: posts.map((post) => ListTile(title: Text(post.body))).toList(),
  )
)

Initial values can also be supplied:

// a stream that is a RxDart ValueObservable
final stream = Repository.of<Post>().findAll();

DataStreamBuilder<List<Post>>(
  stream: stream, // async access to stream
  initialData: stream.value, // sync access to latest value
  builder: (context, List<Post> posts) => ListView(
    children: posts.map((post) => ListTile(title: Text(post.body))).toList(),
  )
)

See tests and the Example tab for a full example.

🛠 Extending #

We can easily extend the class in order to provide our own app-wide defaults.

For instance, we could implement a branded loader:

class BrandedDataStreamBuilder<T> extends DataStreamBuilder<T> {

  static final brandedLoadingBuilder = (context) => Text('Custom branded loading...');

  BrandedDataStreamBuilder({
    Key key,
    @required Stream<T> stream,
    @required DataWidgetBuilder<T> builder,
    DataErrorWidgetBuilder errorBuilder
  }) :
    assert(builder != null),
    super(
      key: key,
      stream: stream,
      builder: builder,
      loadingBuilder: brandedLoadingBuilder,
      errorBuilder: errorBuilder
    );
}

In action:

sample

➕ Collaborating #

Please use Github to open issues and send PRs. Thanks 🙌

📝 License #

MIT

[0.0.6] - 2020-01-06

  • Add support for RxDart ValueStream: automatic initial data

[0.0.5] - 2019-12-09

  • Add support for initial data

[0.0.4] - 2019-12-05

  • Documentation, formatting, changelog

[0.0.3] - 2019-12-05

  • Documentation and examples

[0.0.2] - 2019-12-05

  • Add README and example

[0.0.1] - 2019-12-05

  • First release

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_data_stream_builder/flutter_data_stream_builder.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

Stream<List<int>> _timedCounter() async* {
  int _i = 10;
  while (true) {
    if (_i < 0) break;
    await Future.delayed(Duration(seconds: 1));
    yield List<int>.generate(_i--, (i) => i + 1);
  }
  throw Exception('Mission aborted');
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: DataStreamBuilder<List<int>>(
            stream: _timedCounter(),
            builder: (context, List<int> numbers) => ListView(
              children: numbers.map((n) => ListTile(
                title: Center(child: Text(n.toString())))
              ).toList(),
            )
          ),
        ),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  flutter_data_stream_builder: ^0.0.6

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:flutter_data_stream_builder/flutter_data_stream_builder.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
40
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
78
Overall:
Weighted score of the above. [more]
66
Learn more about scoring.

We analyzed this package on Jan 16, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.0
  • pana: 0.13.4
  • Flutter: 1.12.13+hotfix.5

Health suggestions

Format lib/flutter_data_stream_builder.dart.

Run flutter format to format lib/flutter_data_stream_builder.dart.

Maintenance suggestions

The package description is too short. (-12 points)

Add more detail to the description field of pubspec.yaml. Use 60 to 180 characters to describe the package, what it does, and its target use case.

Package is pre-v0.1 release. (-10 points)

While nothing is inherently wrong with versions of 0.0.*, it might mean that the author is still experimenting with the general direction of the API.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
rxdart ^0.23.1 0.23.1
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test