Flutter获取URL JSON数据遇类型错误:期望Iterable却得到_JsonMap
问题描述
尝试从URL获取JSON数据以测试Flutter与JSON的集成,希望在Flutter UI中展示数据,但运行代码时出现以下错误:
Error: Expected a value of type 'Iterable', but got one of type '_JsonMap'
相关代码如下:
import 'dart:convert'; import 'package:flutter/material.dart'; import '../data/character_api.dart'; import '../model/character.dart'; class CharacterList extends StatefulWidget { const CharacterList({Key? key}) : super(key: key); @override _CharacterListState createState() => _CharacterListState(); } class _CharacterListState extends State<CharacterList> { List<Character> characterList = <Character>[]; void getCharactersfromApi() async { CharacterApi.getCharacters().then((response) { setState(() { Iterable list = json.decode(response.body); characterList = list.map((model) => Character.fromJson(model)).toList(); }); }); } @override void initState() { super.initState(); getCharactersfromApi(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Breaking Bad Characters"), ), body: Container( child: ListView.builder( itemCount: characterList.length, itemBuilder: (context, index) { return ListTile( title: Text("${characterList[index].id}"), subtitle: Text(characterList[index].title), ); }), )); } }
堆栈跟踪信息(翻译后):
错误: 期望类型为 'Iterable<dynamic>' 的值,但得到了类型为 '_JsonMap' 的值 C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 266:49 throw_ C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 99:3 castError C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 485:10 cast C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/classes.dart 638:14 as_C packages/rexello_tests_only/full_custom_test/flutter_json_api/screens/character_list.dart 20:18 <fn> packages/flutter/src/widgets/framework.dart 1133:30 setState packages/rexello_tests_only/full_custom_test/flutter_json_api/screens/character_list.dart 19:7 <fn> C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/zone.dart 1660:54 runUnary C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 147:18 handleValue C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 767:44 handleValueCallback C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 796:13 _propagateToListeners C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 567:5 [_completeWithValue] C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 640:7 callback C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15 <fn>
解决方案
这个错误的核心原因是API返回的JSON不是数组(Iterable),而是单个JSON对象(_JsonMap),但代码里强行把它当成可遍历的数组处理,导致类型不匹配。根据API返回结构的不同,有两种修复方式:
情况1:API返回单个Character对象
如果API返回的是单个角色的JSON对象(比如{"id":1, "title":"Walter White", ...}),直接将其转换为单个Character实例后加入列表:
void getCharactersfromApi() async { CharacterApi.getCharacters().then((response) { setState(() { Map<String, dynamic> characterMap = json.decode(response.body); characterList = [Character.fromJson(characterMap)]; }); }); }
情况2:API返回嵌套在字段中的数组
很多API会把数据数组嵌套在顶层对象的某个字段中(比如{"data": [{"id":1,...}, {"id":2,...}]}),此时先提取对应的数组字段再处理:
void getCharactersfromApi() async { CharacterApi.getCharacters().then((response) { setState(() { Map<String, dynamic> responseMap = json.decode(response.body); Iterable list = responseMap["data"]; // 替换为实际的数组字段名 characterList = list.map((model) => Character.fromJson(model)).toList(); }); }); }
额外优化:统一使用async/await
原代码混合了async和then,建议改用async/await让代码逻辑更清晰:
void getCharactersfromApi() async { final response = await CharacterApi.getCharacters(); setState(() { Map<String, dynamic> responseMap = json.decode(response.body); Iterable list = responseMap["data"]; // 或根据实际结构调整 characterList = list.map((model) => Character.fromJson(model)).toList(); }); }
内容的提问来源于stack exchange,提问作者sumiit yadav
相关产品推荐
相关产品推荐

