remote_state 1.4.0

Dart native js
Flutter Android iOS web

Tools for mapping data from remote sources in Dart, similar to Elm's RemoteData.

RemoteState #

Build & test codecov License: MIT

Tools for mapping data from remote sources in Dart, similar to Elm's RemoteData: https://elmprogramming.com/remote-data.html

PackagePub
remote_statepub package

Slaying a UI Antipattern with Flutter. #

Library inspired by a blog post by Kris Jenkins about How Elm slays a UI antipattern.

What problem does this package solve? #

You are making an API request, and you want to display or do different things based on the status of the request.

Why RemoteState, not RemoteData? #

I gained secondary inspiration from a talk by Jed Watson, A Treatise on State. As much as possible, I try to categorize state correctly in my applications.

The RemoteState approach #

Instead of using a complex object we use a single data type to express all possible request states. This approach makes it impossible to create invalid states.

Usage #

A common use case for RemoteState would be mapping it into a UI transition or component state. Here is an example that uses StateNotifier, found in examples/counter_state_notifier

counter/notifier/counter.dart #


class CounterNotifier extends StateNotifier<RemoteState<int>> {
  var _counterClient = CounterClient();

  CounterNotifier() : super(RemoteState.initial()) {
    getCount();
  }

  getCount() async {
    state = RemoteState.loading();

    state = await RemoteState.guard(() => _counterClient.getCount());
  }

  increment() async {
    state = await RemoteState.guard(() => _counterClient.increment());
  }

  decrement() async {
    state = await RemoteState.guard(() => _counterClient.decrement());
  }
}

main.dart #

class ExampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StateNotifierProvider<CounterNotifier, RemoteState<int>>.value(
        value: CounterNotifier(),
        child: HomePage(),
      ),
    );
  }
}

home.dart #

class HomePage extends StatelessWidget {
  const HomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //2. Resolve counter notifier to update state
    var counterNotifier = Provider.of<CounterNotifier>(context);
    var counterState = Provider.of<RemoteState<int>>(context);

    var textStyle = Theme.of(context).textTheme.display1;
    final fabPadding = EdgeInsets.symmetric(vertical: 5.0);

    return Scaffold(
      appBar: AppBar(
        title: Text('RemoteState with StateNotifier'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You have pushed the button this many times:'),
            //3. Render state changes
            counterState.when(
              initial: () => Text('Not loaded', style: textStyle),
              success: (value) => Text('$value', style: textStyle),
              loading: () => Text('Loading...', style: textStyle),
              error: (_) => Text('Error', style: textStyle),
            ),
          ],
        ),
      ),
      floatingActionButton: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: fabPadding,
            child: FloatingActionButton(
              heroTag: 'inc',
              child: Icon(Icons.add),
              //4. Perform increment action
              onPressed: () => counterNotifier.increment(),
            ),
          ),
          Padding(
            padding: fabPadding,
            child: FloatingActionButton(
              heroTag: 'dec',
              child: Icon(Icons.remove),
              //5. Perform decrement action
              onPressed: () => counterNotifier.decrement(),
            ),
          ),
        ],
      ),
    );
  }
}

API #

RemoteState #

RemoteState<T> is usedto annotate your request variables. It wraps all possible request states into one single union type. Use the parameters to specify.

  • T: The success value type.

RemoteState.initial #

RemoteState.initial is an instance of RemoteState that signifies the request hasn't been made yet.

RemoteState.loading #

RemoteState.loading is an instance of RemoteState that signifies the request has been made, but it hasn't returned any data yet.

RemoteState.success #

RemoteState.success is an instance of RemoteState that signifies the request has completed successfully and the new data (of type T) is available.

RemoteState.error #

RemoteState.error is an instance of RemoteState that signifies the request has failed.

RemoteState.guard #

RemoteState.guard is a static function that converts a Future to RemoteState. It will emit RemoteState.error if the future fails or RemoteState.success if the future completes.

Pattern matching high order functions #

When #

The when method is a high order function that accepts a method for each state and matches the request state with the appropriate callback function. All callbacks are required and must not be null.

MaybeWhen #

The maybeWhen method is a high order function that accepts a method for each state and matches the request state with the appropriate callback function or a fallback callback for missing methods. Only orElse is required.

Map #

The map method is the equivalent of when without the destructuring.

MaybeMap #

The maybeWhen method is the equivalent of when without the destructuring.

State Predicates #

isInitial #

The isInitial predicate returns true if we haven't asked for data yet.

isLoading #

The isLoading predicate returns true if we're loading.

isSuccess #

The isSuccess predicate returns true if we've successfully loaded some data.

isError #

The isError predicate returns true if we've failed to load some data.

Maintainers #

References #

3
likes
85
pub points
30%
popularity

Publisher

cancode.dev

Tools for mapping data from remote sources in Dart, similar to Elm's RemoteData.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (LICENSE)

Dependencies

freezed_annotation

More

Packages that depend on remote_state