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

如何修复Flutter中‘_InternalLinkedHashMap’不是Iterable子类型错误?

问题解决:type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>'

问题根源

你的代码期望API返回数组格式的JSON(如[{"title":"...",...},...]),但实际API返回的是单个对象或包含数组的嵌套对象,导致jsonDecode(response.body)得到的是Map而非Iterable,触发类型转换错误。


解决方案

步骤1:确认API返回结构

先查看调试控制台打印的response.body,判断返回格式:

  • 格式A(嵌套数组):{"data": [{"title":"...", "desc":"...", ...}, ...]}
  • 格式B(单个对象):{"title":"...", "desc":"...", ...}

步骤2:修改仓库代码(Repo)

根据API返回格式二选一:

针对格式A(嵌套数组)
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:medreminder/TipsAndTricks/models/tips_model.dart';

class Repo{
  final _baseUrl = 'http://10.0.2.2:8000/tips';

  // 指定返回类型为List<Tips>,避免类型警告
  Future<List<Tips>> getData() async{
    try {
      final response = await http.get(Uri.parse(_baseUrl));

      if(response.statusCode == 200){
        print(response.body);
        // 先解析为Map,再取出数组部分(key需和API返回的字段名一致,比如是tips就写tips)
        Map<String, dynamic> responseMap = jsonDecode(response.body);
        Iterable it = responseMap['data']; 
        List<Tips> tips = it.map((e) => Tips.fromJson(e)).toList();
        return tips;
      } else {
        // 处理非200状态码,返回空列表
        return [];
      }
    } catch (e) {
      print(e.toString());
      // 捕获异常时返回空列表,避免后续UI报错
      return [];
    }
  }
}
针对格式B(单个对象)
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:medreminder/TipsAndTricks/models/tips_model.dart';

class Repo{
  final _baseUrl = 'http://10.0.2.2:8000/tips';

  Future<List<Tips>> getData() async{
    try {
      final response = await http.get(Uri.parse(_baseUrl));

      if(response.statusCode == 200){
        print(response.body);
        // 解析为单个对象,再包装成列表返回
        Map<String, dynamic> jsonData = jsonDecode(response.body);
        Tips tip = Tips.fromJson(jsonData);
        return [tip];
      } else {
        return [];
      }
    } catch (e) {
      print(e.toString());
      return [];
    }
  }
}

步骤3:修复首页UI更新问题

异步获取数据后需要调用setState刷新UI,同时添加加载状态:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:medreminder/TipsAndTricks/models/tips_model.dart';
import 'package:medreminder/TipsAndTricks/screens/tips_details.dart';
import 'package:medreminder/TipsAndTricks/tips_repo.dart';

class TipsList extends StatefulWidget {
  const TipsList({super.key});

  @override
  State<TipsList> createState() => _TipsListState();
}

class _TipsListState extends State<TipsList> {
  List<Tips> listTips = [];
  Repo repo = Repo();

  getData() async {
    // 接收返回的列表数据,调用setState更新UI
    List<Tips> fetchedTips = await repo.getData();
    setState(() {
      listTips = fetchedTips;
    });
  }

  @override
  void initState() {
    getData();
    super.initState();
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Get.isDarkMode?Colors.grey[600]:Colors.white,
        leading: IconButton(
          onPressed: ()=>Get.back(),
          icon: Icon(Icons.arrow_back_ios,
          color: Get.isDarkMode?Colors.white:Colors.grey
          ),
        ),
        title:  Text("Healthy Tips & Tricks", style: TextStyle(
          color: Get.isDarkMode?Colors.white:Colors.black
        ),),
      ),
      // 列表为空时显示加载指示器,否则渲染列表
      body: listTips.isEmpty 
          ? const Center(child: CircularProgressIndicator())
          : ListView.builder(
              itemCount: listTips.length, 
              itemBuilder: (context, index){
                Tips tips = listTips[index];
                return Card(
                  child: ListTile(
                    title: Text(tips.title),
                    subtitle: Text(tips.source),
                    leading: Image.network(tips.imageUrl),
                    trailing: const Icon(Icons.arrow_forward_ios),
                    onTap: (){
                      Navigator.push(context, MaterialPageRoute(builder: (context) => TipsDetails(tips)));
                    },
                  ),
                );
            })
    );
  }
}

额外优化建议

  1. 给Image.network添加错误占位符,避免图片加载失败导致UI崩溃:
leading: Image.network(
  tips.imageUrl,
  errorBuilder: (context, error, stackTrace) {
    return const Icon(Icons.broken_image);
  },
),
  1. 可以使用FutureBuilder替代手动管理状态,简化代码逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:26:00