You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Riverpod展示多API请求数据时的模型属性访问报错问题

问题解决:Riverpod中Record类型数据的访问错误

问题原因

你通过getItemByUser返回的是Dart的匿名Record(记录类型)(UserTable, ItemModel),这种类型没有userName或itemName这类直接的getter方法,直接访问data.userName会触发类型错误。

解决方案

有两种方式可以正确访问Record中的数据:

方案1:使用位置索引访问匿名Record

匿名Record的成员需要通过$1、$2这样的位置索引来获取($1对应第一个返回值,$2对应第二个),修改展示代码即可:

ref.watch(getProfileAndItem(uid)).when(
  data: (data) => Column(
    children: [
      Text(data.$1.userName), // 获取第一个元素UserTable实例,再访问userName
      Text(data.$2.itemName)  // 获取第二个元素ItemModel实例,再访问itemName
    ],
  ),
  error: (error, stackTrace) => ErrorText(error: error.toString()),
  loading: () => const Loader(),
));

方案2:使用命名Record提升可读性

如果希望代码更直观,可以改用命名Record,需要同时修改数据获取和展示的代码:

  1. 修改getItemByUser方法的返回类型和返回值:
Future<({UserTable user, ItemModel item})> getItemByUser(String uid) async {
  try {
    final value = await Future.wait([
      http.get(Uri.parse('${API.getpurchaseItemByUID}?uid=$uid')),
      http.get(Uri.parse('${API.getUserProfileByUID}?uid=$uid'))
    ]);

    final item = jsonDecode(value[0].body); 
    final profile = jsonDecode(value[1].body);

    // 返回带命名的Record
    return (
      user: UserTable.fromJson(profile[0]),
      item: ItemModel.fromJson(item[0])
    );
  } catch (error) {
    throw error;
  }
}
  1. 更新Provider的泛型定义:
final getProfileAndItem = FutureProvider.family<({UserTable user, ItemModel item}), String>((ref, String uid) async {
  return ref.watch(itemUserProvider).getItemByUser(uid);
});
  1. 在展示代码中通过命名访问数据:
ref.watch(getProfileAndItem(uid)).when(
  data: (data) => Column(
    children: [
      Text(data.user.userName), // 通过命名user获取UserTable实例
      Text(data.item.itemName)  // 通过命名item获取ItemModel实例
    ],
  ),
  error: (error, stackTrace) => ErrorText(error: error.toString()),
  loading: () => const Loader(),
));

内容的提问来源于stack exchange,提问作者hayek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:34:58