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

Flutter报错修复:期望Map<String,dynamic>却得到List<dynamic>

解决Flutter API解析分类列表的类型不匹配问题

问题根源

API返回的JSON是数组(List),但代码尝试用Category.fromJson(仅接受单个Map<String, dynamic>)解析整个数组,导致类型不匹配报错:Expected a value of type 'Map<String, dynamic>', but got one of type 'List<dynamic>'。

修复步骤

1. 扩展Category模型,支持列表解析

在Category类中添加静态方法,用于将JSON数组转换为Category对象列表:

import 'dart:convert';

class Category {
  String? id;
  String? tenantId;
  String? userId;
  String? name;
  String? description;
  String? createdAt;
  String? updatedAt;

  Category(
      {this.id,
      this.tenantId,
      this.userId,
      this.name,
      this.description,
      this.createdAt,
      this.updatedAt});

  Category.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    tenantId = json['tenant_id'];
    userId = json['user_id'];
    name = json['name'];
    description = json['description'];
    createdAt = json['created_at'];
    updatedAt = json['updated_at'];
  }

  // 新增:将JSON数组转为Category列表
  static List<Category> fromJsonList(List<dynamic> jsonList) {
    return jsonList.map((json) => Category.fromJson(json)).toList();
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = id;
    data['tenant_id'] = tenantId;
    data['user_id'] = userId;
    data['name'] = name;
    data['description'] = description;
    data['created_at'] = createdAt;
    data['updated_at'] = updatedAt;
    return data;
  }
}

2. 修改API调用函数,返回正确的列表类型

更新getMceaCategories,明确返回类型为Future<List<Category>>,并使用新增的fromJsonList解析数组:

import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:mcea_master_application/config/config.dart';
import 'package:mcea_master_application/models/CategoryModel.dart';

final String urlCategories = '${Config.baseUrl}categories';

// 明确返回类型为Future<List<Category>>
Future<List<Category>> getMceaCategories() async {
  final response = await http.get(Uri.parse(urlCategories), headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Bearer 6|b8Wi0V95n3fgZyCg3DiJFymdx10jZsX2K58vpVcq',
  });
  if (response.statusCode == 200) {
    // 解析为List后,用fromJsonList转成Category列表
    List<dynamic> jsonList = jsonDecode(response.body);
    return Category.fromJsonList(jsonList);
  } else {
    throw Exception('Falha ao carregar as categorias!');
  }
}

3. 调整页面代码,使用模型对象访问属性

因为Future返回的是List<Category>,所以在FutureBuilder中直接通过模型属性访问,而非Map索引:

import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:mcea_master_application/config/config.dart';
import 'package:mcea_master_application/config/mcea-api.dart';
import 'package:mcea_master_application/models/CategoryModel.dart';

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

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.black,
        title: Text(Config.title),
      ),
      body: FutureBuilder<List<Category>>(
          future: getMceaCategories(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              final categories = snapshot.data!;
              return ListView.builder(
                  itemCount: categories.length,
                  itemBuilder: (context, index) {
                    final category = categories[index];
                    return ListTile(
                      title: Text(category.name ?? 'Sem nome'),
                    );
                  });
            }
            if (snapshot.hasError) {
              print(snapshot.error);
              return Center(child: Text('Erro ao carregar categorias'));
            }
            return const Center(
              child: CircularProgressIndicator(),
            );
          }),
    );
  }
}

关键说明

  • 移除原页面中无用的dart:html和dart:js导入,避免不必要的依赖
  • 使用category.name ?? 'Sem nome'处理可能为null的属性,防止空指针异常
  • 明确FutureBuilder的泛型类型List<Category>,提升代码可读性和类型安全性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:05:17