async_controller 1.0.2

  • Readme
  • Changelog
  • Example
  • Installing
  • 74

async_controller #

A library for managing asynchronously loaded data in Flutter.

Do I need this? #

If your project contains isLoading flags or error handling duplicated across many pages, you may benefit from this package. It will let you write async loading with minimal amount of boilerplate. Unlike FutureBuilder, AsyncController ensures that fetch is performed only when necessary. You may configure when controller should refresh using provided Refreshers. More on that later.

final _controller = AsyncController<String>.method(() async {
  await Future<void>.delayed(Duration(seconds: 1));
  return 'Hello world';

class Minimal extends StatelessWidget {
  Widget build(BuildContext context) {
    return _controller.buildAsyncData(builder: (_, data) {
      // This builder runs only if data is available.
      // buildAsyncData takes care of other situations
      return Text(data);

Example: minimal.dart

Pull to refresh #

AsynController provides a method that you can plug right into a RefreshIndicator. Also, if user tries to refresh while loading is already pending the previous loading will be cancelled.

final _controller = AsyncController.method(fetchSomething);
  onRefresh: _controller.performUserInitiatedRefresh,
  child: _controller.buildAsyncData(builder: buildContent),

Example: pull_to_refresh.dart

Loading and error handling #

AsyncController used with buildAsyncData, automatically handles loading and error states. There is no need to manually change isLoading flag, or catch. AsyncController will do the right thing by default, while allowing for customizations.

final _controller = AsyncController.method(() => throw 'error');
_controller.buildAsyncData(builder: builder: (_, data) {
  // this function runs only on success
  return Text(data);

Example: failure_handling.dart

Custom loading and error handling #

Loading and error handling widgets are created by AsyncDataDecoration. You may override their behavior by creating custom AsyncDataDecoration. The same decorator can then be used in every AsyncData in your app.

class CustomAsyncDataDecoration extends AsyncDataDecoration {
  Widget buildError(BuildContext context, dynamic error, VoidCallback tryAgain) {
    return Text('Sorry :(');

final _controller = AsyncController.method(() => throw 'error');
  builder: buildContent,
  decorator: CustomAsyncDataDecoration(),

Example: failure_handling_custom.dart

Automatic refresh #

Every AsyncController can be customized to automatically refresh itself in certain situations.

  • Refresh after network connection comes back.
  • Refresh data every X seconds.
controller.addRefresher(PeriodicRefresher(Duration(seconds: 3)));
  • Refresh after user resumes the app from background.
  • Refresh when another ChangeNotifier updates.
  1. Easy to use customization through AsyncDataDecoration.
class MyDecoration extends AsyncDataDecoration {
  Widget buildNoDataYet(BuildContext context) => MyProgressIndicator();

Example: refreshers_page.dart

Paginated data

PagedAsyncController class, which extends AsyncController, is capable of loading data in pages.

Example: paged_loading.dart

Filtering & searching

AsyncController can be extended to implement filtering & searching. You do this by extending FilteringAsyncController. Example: sort_and_search.dart

Async button

Not really related to AsyncController, but still useful. AsyncButton is a button that handles async onPressed methods. When user presses the button:

  • starts the async operation provided in onPressed method
  • shows loading indicator
  • blocks the user interface to avoid typing on keyboard or leaving the page
  • in case error, shows snackbar
  • finally, cleans up loading indicator & interface lock
  // AsyncButtons takes a child like typical button
  child: const Text('Press me!'),
  // AsyncButton accepts async onPressed method and handles it
  onPressed: () => Future.delayed(Duration(seconds: 1)),
  // Through builder method we can support any kind of button
  builder: (x) => FlatButton(
    onPressed: x.onPressed,
    child: x.child,

Example: async_button_example.dart

Interaction with other packages #

AsyncController plays nicely with others. It implements ChangeNotifier and ValueListenable - classes commonly used inside Flutter. You can use it with any state management / dependency injection that you want. The example project includes samples for flutter_hooks and provider.

Example 1: hooks_example.dart

Example 2: provider_example.dart

[1.0.2] - 10.02.2020 #

  • fix snapshot getter
  • add last fetch timing

[1.0.1] - 10.02.2020 #

  • improve refreshers
  • reintroduce performFetch method

[1.0.0] - 09.02.2020 #

  • release stable version
  • fix few bugs
  • add better logging
  • rewrite paged loading

[0.0.3] - 09.12.2019 #

  • fix missing removeListener

[0.0.2] - 09.09.2019 #

  • Formatting and README improvements

[0.0.1] - 09.09.2019 #

  • Initial release


import 'package:example/helpers.dart';
import 'package:example/hooks_example.dart';
import 'package:example/paged_loading.dart';
import 'package:example/refreshers_page.dart';
import 'package:example/sort_and_search.dart';
import 'package:example/stream.dart';
import 'package:flutter/material.dart';

// ignore: implementation_imports
import 'package:async_controller/src/debugging.dart';

import 'async_button_example.dart';
import 'failure_handling.dart';
import 'failure_handling_custom.dart';
import 'minimal.dart';
import 'paged_loading_simple.dart';
import 'provider_example.dart';
import 'pull_to_refresh.dart';
import 'translator/translator_page.dart';

void main() {
  internalDebugLogEnabled = true;

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ExampleSwitcher(),

class ExampleSwitcher extends StatelessWidget {
  Widget build(BuildContext context) {
    final examples = <ExamplePage>[

    return Scaffold(
      appBar: AppBar(
        title: Text('async_controller'),
      body: ListView.builder(
        itemCount: examples.length,
        itemBuilder: (context, i) {
          final example = examples[i];
          return ListTile(
            title: Text(example.title),
            onTap: () {
              final route =
                  MaterialPageRoute<void>(builder: (context) => examples[i]);

Use this package as a library

1. Depend on it

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

  async_controller: ^1.0.2

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:async_controller/async_controller.dart';
Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

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

  • Dart: 2.8.4
  • pana: 0.13.9+1
  • Flutter: 1.17.3

Analysis suggestions

Package does not support Flutter platform linux

Because of import path [package:async_controller/async_controller.dart, package:async_controller/src/refreshers.dart, package:connectivity/connectivity.dart]

Package does not support Flutter platform windows

Because of import path [package:async_controller/async_controller.dart, package:async_controller/src/refreshers.dart, package:connectivity/connectivity.dart]

Package not compatible with SDK dart

because of import path [async_controller]


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
connectivity ^0.4.6 0.4.9
flutter 0.0.0
Transitive dependencies
collection 1.14.12 1.14.13
connectivity_for_web 0.3.0
connectivity_macos 0.1.0+3
connectivity_platform_interface 1.0.6
flutter_web_plugins 0.0.0
js 0.6.2
meta 1.1.8 1.2.0
plugin_platform_interface 1.0.2
sky_engine 0.0.99
typed_data 1.1.6 1.2.0
vector_math 2.0.8
Dev dependencies
lint any