【问题标题】:RiverPod - How to await using FutureProvider on AsyncValue not in widgetRiverPod - 如何在不在小部件中的 AsyncValue 上等待使用 FutureProvider
【发布时间】:2021-05-30 08:08:19
【问题描述】:

我需要从 Firebase Cloud Firestore 获得 1 个字段 1 次。我如何使用 Widget 构建之外的提供者来实现这一点?

以下是我的综合提供商。 appStartupProvider 是一个 FutureProvider,我想从 firestore 的这个 1 字段中获取 bool 值。但是,appStartupProvider 中的 await 声明“'await' 应用于 'AsyncValue',这不是 'Future'”。

final accountStreamProvider = StreamProvider<Account>((ref) {
  final database = ref.watch(databaseProvider);
  return database != null ? database.accountStream() : const Stream.empty();
});

final _accountSetupCompleteProvider = Provider<AsyncValue<bool>>((ref) {
  return ref
      .watch(accountStreamProvider)
      .whenData((account) => account?.accountSetupComplete ?? false);
});

final appStartupProvider = FutureProvider<bool>((ref) async {
  final accountSetupComplete = await ref.watch(_accountSetupCompleteProvider);

  return accountSetupComplete;
});

这里显然缺少一些关于组合提供程序和 AsyncValue 的关键知识,但我正在尝试完成RiverPod Combining Providers 页面上所述的情况,我看到正在使用等待。

【问题讨论】:

  • 你解决了吗?我目前正在学习颤振,并且与 Riverpod 提供商有同样的问题。我想解析提供者的返回值,以便可以在另一个提供者中使用该值,但找不到正确的方法。
  • @groo 请参阅下面的答案。 stackoverflow.com/a/66955043/7259858

标签: flutter dart flutter-provider riverpod


【解决方案1】:

您发帖时文档中的示例不正确。它已经更新,现在是正确的。

你可以这样写:

final accountStreamProvider = StreamProvider<Account?>((ref) {
  final database = ref.watch(databaseProvider);
  return database != null ? database.accountStream() : const Stream.empty();
});

final _accountSetupCompleteProvider = FutureProvider<bool>((ref) async {
  final account = await ref.watch(accountStreamProvider.last);
  return account?.accountSetupComplete ?? false;
});

final appStartupProvider = FutureProvider<bool>((ref) async {
  final accountSetupComplete = await ref.watch(_accountSetupCompleteProvider.future);
  return accountSetupComplete;
});

或者:

final accountStreamProvider = StreamProvider<Account?>((ref) {
  final database = ref.watch(databaseProvider);
  return database != null ? database.accountStream() : const Stream.empty();
});

final _accountSetupCompleteProvider = Provider<AsyncValue<bool>>((ref) {
  return ref
      .watch(accountStreamProvider)
      .whenData((account) => account?.accountSetupComplete ?? false);
});

final appStartupProvider = Provider<bool>((ref) {
  final accountSetupComplete = ref.watch(_accountSetupCompleteProvider).maybeWhen(
        data: (data) => data, 
        orElse: () => false,
      );

  return accountSetupComplete;
});

【讨论】:

    【解决方案2】:

    await 的用法可通过以下方式获得:

    例子

    final carsListFutureProvider = FutureProvider<List<Car>>((ref) {
      final backend = ref.watch(backendProvider);
      return backend.getList(pathName, (json) => Car.fromJson(json));
    });
    
    final carFutureProvider = FutureProvider.family<Car?,int>((ref,id) async {
      final list = await ref.watch(carsListFutureProvider.future);
      return list.firstWhereOrNull((e) => e.id == id);
    });
    

    目前文档似乎包含不正确的代码示例。 issue

    【讨论】:

      猜你喜欢
      • 2021-04-01
      • 2022-10-19
      • 2021-03-23
      • 2020-11-11
      • 2021-12-24
      • 1970-01-01
      • 2022-07-28
      • 2021-02-02
      • 2022-12-14
      相关资源
      最近更新 更多