2

I was wondering if there is a way how I can use a Future Builder together with a FutureOr<T> typed future-parameter?

Hamed
  • 5,867
  • 4
  • 32
  • 56

1 Answers1

1

The simplest way would be to always convert the FutureOr<T> to a Future<T>. The Future class has numerous constructors that can do that:

Any of them should work, but if I'd use Future<T>.value or Future<T>.new:

FutureBuilder(future: Future.value(maybeFuture), ...)

If that isn't desirable (waiting on a Future<T> created from an existing T entails an extra iteration of the event loop), then it's pretty simple to create your own FutureOrBuilder widget that's like a FutureBuilder but that invokes its AsyncWidgetBuilder callback synchronously if possible:

class FutureOrBuilder<T> extends StatelessWidget {
  final FutureOr<T>? futureOrValue;

  final T? initialData;

  final AsyncWidgetBuilder<T> builder;

  const FutureOrBuilder({
    super.key,
    FutureOr<T>? future,
    this.initialData,
    required this.builder,
  }) : futureOrValue = future;

  @override
  Widget build(BuildContext context) {
    final futureOrValue = this.futureOrValue;
    if (futureOrValue is T) {
      return builder(
        context,
        AsyncSnapshot.withData(ConnectionState.done, futureOrValue),
      );
    } else {
      return FutureBuilder(
        future: futureOrValue,
        initialData: initialData,
        builder: builder,
      );
    }
  }
}
jamesdlin
  • 81,374
  • 13
  • 159
  • 204
  • The issue with this is, that it will init a loading sequence even if the value is already present. – Paul Jun 02 '23 at 08:20
  • @Paul Have you observed that? If I use a `Future.value` with `FutureBuilder`, I don't see the initial data rendered, although possibly I'm being lucky (or being unlucky and dropping a frame). But if it's actually a problem, I've updated my answer to provide a way to synchronously build when possible. – jamesdlin Jun 02 '23 at 19:13
  • Yes, I think Flutter might always start with a loading state, and if rendering is too slow (many loadings or heavy visuals) it will actually first build in a loading state and only later rebuild it. But your new solution is great! The flutter team should do this a default!!! – Paul Jun 03 '23 at 13:25