Flutter - 提取到 FutureBuilder 的 JSON 反序列化数据返回空值

Posted

技术标签:

【中文标题】Flutter - 提取到 FutureBuilder 的 JSON 反序列化数据返回空值【英文标题】:Flutte - JSON deserialized data fetched to FutureBuilder return null value 【发布时间】:2021-06-14 01:15:25 【问题描述】:

我正在尝试通过从 API 获取的数据通过 FutureBuilder 返回照片的 ListView。在我的服务中将值添加到 List 并正确分配时,获取到 List Builder 的值是 null。我不知道为什么调用服务方法返回 Future 会返回 null 列表。

我的模特:

class Photo 
  String id;
  String photoDesc;
  String photoAuthor;
  String photoUrlSmall;
  String photoUrlFull;
  String downloadUrl;
  int likes;

  Photo(
      this.id,
      this.photoDesc,
      this.photoAuthor,
      this.photoUrlSmall,
      this.photoUrlFull,
      this.downloadUrl,
      this.likes);

  Photo.fromJson(Map<String, dynamic> json) 
    id = json['id'];
    photoDesc = json['description'] != null
        ? json['description']
        : json['alt_description'];
    photoAuthor = json['user']['name'] != null
        ? json['user']['name']
        : json['user']['username'];
    photoUrlSmall = json['urls']['small'];
    photoUrlFull = json['urls']['full'];
    downloadUrl = json['links']['download'];
    likes = json['likes'];
  

我的服务:

Future<List<Photo>> getRandomData1() async 
    List<Photo> randomPhotos;
    _response = await http.get(Uri.parse(
        '$unsplashUrl/photos/random/?client_id=$_key.accessKey&count=30'));
    if (_response.statusCode == 200) 
      return randomPhotos = (json.decode(_response.body) as List).map((i) 
        Photo.fromJson(i); 
        print(Photo.fromJson(i).id); // **i.e. printing returns proper values**
          ).toList();
         else 
          print(_response.statusCode);
          throw 'Problem with the get request';
        
      

我的建造者:

class RandomPhotosListView extends StatefulWidget 
  @override
  _RandomPhotosListViewState createState() => _RandomPhotosListViewState();


class _RandomPhotosListViewState extends State<RandomPhotosListView> 
  final UnsplashApiClient unsplashApiClient = UnsplashApiClient();
  Future _data;

  ListView _randomPhotosListView(data) 
    return ListView.builder(
        itemCount: data.length,
        itemBuilder: (context, index) 
          return Text("$data[index]"); 
        );
  

  @override
  void initState() 
    super.initState();
    _data = unsplashApiClient.getRandomData1();
  

  @override
  Widget build(BuildContext context) 
    return FutureBuilder(
      future: _data,
      builder: (context, snapshot) 
        print(snapshot.data);          // i.e. snapshot.data here is list of nulls
        if (snapshot.connectionState == ConnectionState.waiting) 
          return Center(child: CircularProgressIndicator());
         else if (snapshot.hasError) 
          print(snapshot.error);
          return Text("error: $snapshot.error");
         else if (snapshot.hasData) 
          return _randomPhotosListView(snapshot.data);
        
        return Center(child: CircularProgressIndicator());
      ,
    );
  

【问题讨论】:

乍一看,您的 map 函数没有返回解析的对象,这可能是问题所在。试试return Photo.fromJson(i).map(i =&gt; Photo.fromJson(i)).toList() 你需要检查你的connectionState是否等于ConnectionState.done,然后检查snapshot.hasData或snapshot.error 谢谢@daddygames!这么小的事情,但我浪费了 3 小时试图解决它:D @sdobrzan 它发生在我们所有人身上。这是 SO 的重要方面之一。如果您对我的回答感到满意,请标记为这样。编码愉快! 【参考方案1】:

您遇到此问题的原因是您需要在映射函数中返回已解析的对象。

解决方案 #1 - 将 return 关键字添加到现有代码中

return randomPhotos = (json.decode(_response.body) as List).map((i) 
 return Photo.fromJson(i); // <-- added return keyword here
).toList();

解决方案 #2 - 使用箭头定义回报

此解决方案适合您的代码,因为您没有操作 Photo 对象或映射中的任何其他数据。

return randomPhotos = (json.decode(_response.body) as List).map((i) => Photo.fromJson(i)).toList();

任何一种解决方案都应该有效。选择适合您的编码风格和需求的。

【讨论】:

以上是关于Flutter - 提取到 FutureBuilder 的 JSON 反序列化数据返回空值的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Bloc:将 Firestore 数据提取到模型中

Flutter - 提取到 FutureBuilder 的 JSON 反序列化数据返回空值

Flutter 位置包帮助:我想将用户证明的坐标提取到单独的 var/string 或 double 中

Flutter/Dart 仅提取日期和时间? [复制]

如何在 dart/flutter 中提取 JSON 子数据

在 Flutter 中提取 JSON 数据时遇到问题