Skip to content

Easily consume and produce loading/error/data states in your Flutter app

License

Notifications You must be signed in to change notification settings

passsy/data_state

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DISCONTINUED

This package has been integrated (and improved) into Flutter Data


data_state

tests pub.dev license

Easily produce and consume loading/error/data states in your application.

DataState is a StateNotifier-based alternative to AsyncSnapshot.

  • Produce events from DataStateNotifier, Future, Stream, RxDart ValueStream
  • Consume events through DataStateNotifier, Stream

👩🏾‍💻 Usage

Consuming state

Flutter example:

(Note: This example depends on flutter_data_state which is a separate package)

@override
Widget build(BuildContext context) {
  return DataStateBuilder<List<Post>>(
    notifier: () => repo.watchPosts(),
    builder: (context, state, notifier, _) {
      return Column(
        children: [
          if (state.isLoading)
            CircularProgressIndicator(),
          if (state.hasException)
            ExceptionWidget(state.exception),
          if (state.hasModel)
            ShowPost(state.model),
        ],
      );
    }
  );
}

The notifier features a reload function, useful to restart a data loading cycle. It can be combined with a gesture detector or reloader widget:

Example 1:

GestureDetector(
  onTap: () => notifier.reload(), // will trigger a rebuild with isLoading = true
  child: _child,
)

Example 2:

RefreshIndicator(
  onRefresh: notifier.reload,
  child: _child,
),

Future & Stream input support

This package exposes an extension on Future<T> Function() called asDataNotifier.

It allows to turn any future into a DataStateNotifier callback to leverage caching and reloading capabilities.

Example 1:

final notifier = (() => future).asDataNotifier;

Example 2:

final notifier = (() {
  if (Random().nextInt(10) > 4) {
    return Future<String>.error('Error!');
  }
  return Future.delayed(
    Duration(seconds: 1),
    () => 'HELLO RANDOM: ${Random().nextInt(100)}!',
  );
}).asDataNotifier;

Same for Streams and ValueStreams:

final notifier = (() => stream).asDataNotifier;

Consuming streams

Want to consume events via streams?

DataStateNotifier actually exposes an RxDart ValueStream:

@override
Widget build(BuildContext context) {
  final stream = repo.watchPosts().stream;
  return StreamBuilder<List<Post>>(
    initial: stream.value,
    stream: stream,
    builder: (context, snapshot) {
      // snapshot as usual
    }
  );
}

This is the anatomy of an immutable DataState object:

final state = DataState({
  T model,
  bool isLoading = false,
  Object exception,
  StackTrace stackTrace,
});

🎸 Producing state

Example:

DataStateNotifier<List<Post>> watchPosts() {
  final notifier = DataStateNotifier<List<Post>>(
    DataState(model: getLocalPosts()),
    reload: (notifier) async {
      notifier.state = notifier.state.copyWith(isLoading: true);
      try {
        notifier.data = await loadPosts();
      } catch (error, stackTrace) {
        notifier.data = notifier.data.copyWith(exception: error, stackTrace: stackTrace);
      }
    },
  );

  // kick off cycle
  return notifier..reload();
}

The DataStateNotifier constructor takes:

  • state as the first positional argument
  • reload and onError as optional named arguments

⁉ FAQ

Why is DataState not a freezed union?

This would allow us to do the following destructuring:

state.when(
  data: (data) => Text(data),
  loading: () => const CircularProgressIndicator(),
  error: (error, stackTrace) => Text('Error $error'),
);

This turns out to be impractical in data-driven Flutter apps as there are cases where we need to render loading/error messages in addition to data – not instead of data.

Does DataStateNotifier depend on Flutter?

No. It can used with pure Dart.

➕ Collaborating

Please use Github to ask questions, open issues and send PRs. Thanks!

📝 License

See LICENSE

About

Easily consume and produce loading/error/data states in your Flutter app

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Dart 100.0%