Flutter GetX调用REST API报错:_InternalLinkedHashMap无法转为List
问题分析与解决
核心错误原因
报错_TypeError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List')的根源是:
- 错误地将API返回的单个JSON对象解析成了
List类型,但根据ShowList模型,接口返回的是包含products字段的单个对象,而非数组。 - 控制器中定义的
showlist是List<ShowList>类型,但实际只需要存储单个ShowList实例。 - UI层错误地遍历
showlist列表,实际应该遍历ShowList内部的products.data商品列表。
分步修正代码
1. 修正ApiManager(接口请求层)
将JSON解析逻辑改为解析单个Map,并返回单个ShowList对象:
import 'dart:convert'; import 'package:foodello/model/ShowListing.dart'; import 'package:http/http.dart' as http; class ApiManager { static Future<ShowList> getShowList() async { String baseURL = 'https://westmarket.herokuapp.com/api/v1'; String userId = '62f4ecf82b6e81e77059b332'; // 修正URL路径:去掉多余的冒号 String url = '$baseURL/user/$userId/products'; final response = await http.get(Uri.parse(url)); // 解析为单个Map而非List Map<String, dynamic> jsonResponse = json.decode(response.body); return ShowList.fromJson(jsonResponse); } }
2. 修正HomeController(状态管理层)
将showlist改为单个ShowList的可观察对象:
import 'package:flutter/material.dart'; import 'package:foodello/model/ShowListing.dart'; import 'package:get/get.dart'; import 'package:foodello/services/apiManager.dart'; class HomeController extends GetxController { // 定义为可观察的单个ShowList对象,初始值为null var showlist = Rx<ShowList?>(null); @override void onInit() { fetchShowList(); super.onInit(); } void fetchShowList() async { try { ShowList post = await ApiManager.getShowList(); showlist.value = post; } catch (e) { // 捕获异常,方便调试 print('请求失败:$e'); } } }
3. 修正首页UI代码
遍历products.data列表展示商品:
Obx( () { // 先判断数据是否存在 if (controller.showlist.value == null) { return const Center(child: CircularProgressIndicator()); } final productList = controller.showlist.value!.products.data; return Expanded( child: ListView.builder( itemCount: productList.length, itemBuilder: (BuildContext context, index) { var singleProduct = productList[index]; return Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Container( height: 200, width: 100, child: Column( children: [ Text(singleProduct.name), Text(singleProduct.price.toString()), Text(singleProduct.initialQuantity.toString()), Text(singleProduct.soldQuantity.toString()), ], ), ), ], ); }, ), ); }, )
额外注意点
- 原URL中的
/user/:$userId/products存在错误,:$userId会被当作路径的一部分,正确写法是/user/$userId/products,否则接口可能返回错误数据。 - 建议在请求中增加异常捕获,避免因接口错误导致页面崩溃。
内容的提问来源于stack exchange,提问作者K'man Amuda Jr.
相关产品推荐
相关产品推荐

