Riverpod futureProvider.FAMILY返回NULL

发布于 2025-02-10 10:16:56 字数 2098 浏览 4 评论 0 原文

我有一个带有家庭参数的Future -provider,如下所示:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class I_Rem_Params {
  final String adminID;
  final String companyID;
  final int month;
  I_Rem_Params(
      {required this.adminID, required this.companyID, required this.month});
}

final iRemReportsFamily =
    FutureProvider.family<double, I_Rem_Params>((ref, iremparams) async {
  final db = FirebaseFirestore.instance;
  final admins = db.collection("Admins");
  final admin = admins.doc(iremparams.adminID);
  final companies = admin.collection("Companies");
  final company = companies.doc(iremparams.companyID);
  final imports = company.collection("Imports");
  final getImports = await imports.get();
  final val = getImports.docs.length.toDouble();
  print("value at provider : " + val.toString());
  return val;
});

我正在打印FutureProvider在下面发送的值之前:

value at provider : 2

我在widget sine处得到和打印异步的Asyncvalue:

AsyncValue<double> juneTotalValue = ref.watch(iRemReportsFamily(
    I_Rem_Params(
        adminID: adminID!, companyID: widget.companyID, month: 5)));

print("value at widget : " + juneTotalValue.value.toString());
print("runtimetype at widget : " + juneTotalValue.runtimeType.toString());

:如下:如下:如下:

value at widget : null
runtimetype at widget : AsyncLoading<double>

Asyncvalue在widget sine上按照下面的方式打印出来:并注入Asyncvalue,如下所示

....... children: [
                        juneTotalValue.when(
                            data: (data) => Text(data.toString()),
                            error: (error, stack) => Text(error.toString()),
                            loading: () => const CircularProgressIndicator()),
                        const SizedBox(
                          height: 38,
                        ),........

如下:如下:如下:处理异步的处理不显示未来推销员发送的2的值,而仅显示圆形ProgressIndicator()的加载窗口小部件。

问题:尽管Future -Provider发送了一个数字,但为什么异步是无效的?

I have a FutureProvider with Family parameters as below:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class I_Rem_Params {
  final String adminID;
  final String companyID;
  final int month;
  I_Rem_Params(
      {required this.adminID, required this.companyID, required this.month});
}

final iRemReportsFamily =
    FutureProvider.family<double, I_Rem_Params>((ref, iremparams) async {
  final db = FirebaseFirestore.instance;
  final admins = db.collection("Admins");
  final admin = admins.doc(iremparams.adminID);
  final companies = admin.collection("Companies");
  final company = companies.doc(iremparams.companyID);
  final imports = company.collection("Imports");
  final getImports = await imports.get();
  final val = getImports.docs.length.toDouble();
  print("value at provider : " + val.toString());
  return val;
});

I am printing the value before sent by FutureProvider as below:

value at provider : 2

I am getting and printing the AsyncValue at widget side as below:

AsyncValue<double> juneTotalValue = ref.watch(iRemReportsFamily(
    I_Rem_Params(
        adminID: adminID!, companyID: widget.companyID, month: 5)));

print("value at widget : " + juneTotalValue.value.toString());
print("runtimetype at widget : " + juneTotalValue.runtimeType.toString());

AsyncValue printed as below on widget side:

value at widget : null
runtimetype at widget : AsyncLoading<double>

And injecting the AsyncValue as follows:

....... children: [
                        juneTotalValue.when(
                            data: (data) => Text(data.toString()),
                            error: (error, stack) => Text(error.toString()),
                            loading: () => const CircularProgressIndicator()),
                        const SizedBox(
                          height: 38,
                        ),........

Handling of AsyncValue not display value of 2 sent by FutureProvider but only display loading widget of CircularProgressIndicator().

QUESTION: Why AsyncValue is Null despite there is a number sent by FutureProvider ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独自唱情﹋歌 2025-02-17 10:16:56

这主要与您如何创建FutureProvider有关。

因为。家庭修饰符为每个独特价值创建一个新的提供商,您需要确认输入值的 hashcode 每次调用提供商时都是相同的。如果不是这样,每次都会创建一个新的提供商。如果您正在使用ref.watch,则可以陷入循环中:

  1. ref.watch创建futureProvider1(使用输入“ 1”)
  2. ,当futureProvider1完成时,它会触发ref.watch Line再次创建
  3. Ref.Watch create funerProvider2(使用输入”(使用输入”(使用“输入”) 2“)
  4. 当futureProvider2完成后,它再次触发参考线再次
  5. 重复,

也可以在参数限制 RiverPod文档的部分。通常,您应该使用原始数据类型(例如int,bool,double或string)创建。家庭提供商。

如果您需要使用其他东西,那么您需要使用诸如

class Person {
  const Person(this.name);

  final String name;

  @override
  bool operator ==(Object other) =>
    identical(this, other) ||
    other is Person &&
    runtimeType == other.runtimeType &&
    name == other.name;

  @override
  int get hashCode => name.hashCode;
}

This mainly has to do with how you are creating your FutureProvider.family.

Since the .family modifier creates a new provider for each unique value that is passed to it, you need to confirm that the hashcode of the input value is the same each time you call the provider. If it's not, a new provider will be created each time. If you're using ref.watch, you can get caught in a loop:

  1. ref.watch creates FutureProvider1 (using input "1")
  2. When FutureProvider1 completes, it triggers the ref.watch line again
  3. ref.watch creates FutureProvider2 (using input "2")
  4. When FutureProvider2 completes, it triggers the ref.watch line again
  5. Repeat

This is also pointed out in the Parameter restrictions section of the Riverpod docs. In general, you should create your .family providers using a primitive data type (like int, bool, double, or string).

If you need to use something else, then you'll need to override the hashcode method of your object using a package like equatable.

class Person {
  const Person(this.name);

  final String name;

  @override
  bool operator ==(Object other) =>
    identical(this, other) ||
    other is Person &&
    runtimeType == other.runtimeType &&
    name == other.name;

  @override
  int get hashCode => name.hashCode;
}
各空 2025-02-17 10:16:56

Randal的解决方案解决了问题。

Randal's solution has solved the problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文