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

Flutter调用API遭遇TypeError,无法解析JSON数据求助

从API读取数据时遭遇TypeError错误,模型解析问题求助

错误截图:
错误截图

请求代码

import '../models/LocationListApi.dart';
import 'package:http/http.dart' as http;
import 'dart:convert' as convert;

class Network {
  static Uri url = Uri.parse(
      "http://pelak.puladin.com/laravel-api/api/v1/places?category_id=11");

  static List<PlacesEntity> location = [];

  static void getData() async {
    location.clear();
    var response = await http.get(url);
    var jsonDecode = convert.jsonDecode(response.body);

    var finalResponse = PlacesEntity.fromJson(jsonDecode['data']);

    for (var json in jsonDecode) {
      location.add(PlacesEntity.fromJson(json));
    }

    print(jsonDecode);
  }
}

模型代码

// ignore_for_file: file_names

class PlacesEntity {
  List<Place> places;

  PlacesEntity({
    required this.places,
  });

  factory PlacesEntity.fromJson(Map<String, dynamic> json) {
    return PlacesEntity(
      places: List<Place>.from(json['places'].map((x) => Place.fromJson(x))),
    );
  }
}

class Place {
  int id;
  int pelak;
  String name;
  String intro;
  String description;
  String latitude;
  String longitude;
  String address;
  String phone;
  String email;
  String website;
  String instagram;
  String image;
  String category;
  String ads;
  String adsLink;

  Place({
    required this.id,
    required this.pelak,
    required this.name,
    required this.intro,
    required this.description,
    required this.latitude,
    required this.longitude,
    required this.address,
    required this.phone,
    required this.email,
    required this.website,
    required this.instagram,
    required this.image,
    required this.category,
    required this.ads,
    required this.adsLink,
  });

  factory Place.fromJson(Map<String, dynamic> json) {
    return Place(
      id: json['id'],
      pelak: json['pelak'],
      name: json['name'],
      intro: json['intro'],
      description: json['description'],
      latitude: json['latitude'],
      longitude: json['longitude'],
      address: json['address'],
      phone: json['phone'],
      email: json['email'],
      website: json['website'],
      instagram: json['instagram'],
      image: json['image'],
      category: json['category'],
      ads: json['ads'],
      adsLink: json['ads_link'],
    );
  }
}

class MyJson {
  PlacesEntity data;
  int status;

  MyJson({
    required this.data,
    required this.status,
  });

  factory MyJson.fromJson(Map<String, dynamic> json) {
    return MyJson(
      data: PlacesEntity.fromJson(json['data']),
      status: json['status'],
    );
  }
}

问题分析与解决方案

  1. 核心错误原因:

    • getData()方法中错误遍历了整个jsonDecode对象(这是包含data和status的Map),而非jsonDecode['data']['places']数组,直接遍历Map会触发TypeError,因为Map不属于可迭代列表类型。
    • 已定义的MyJson类(用于解析完整API响应)未被使用,代码逻辑混乱。
  2. 修正后的请求代码:

import '../models/LocationListApi.dart';
import 'package:http/http.dart' as http;
import 'dart:convert' as convert;

class Network {
  static Uri url = Uri.parse(
      "http://pelak.puladin.com/laravel-api/api/v1/places?category_id=11");

  static List<Place> location = []; // 改为存放Place对象的列表,而非PlacesEntity

  static void getData() async {
    location.clear();
    var response = await http.get(url);
    var jsonDecode = convert.jsonDecode(response.body);

    // 使用MyJson解析完整响应
    MyJson myJson = MyJson.fromJson(jsonDecode);
    // 直接获取places列表赋值给location
    location = myJson.data.places;

    print(location.length); // 打印列表长度验证解析结果
  }
}
  1. 模型代码无需修改,需明确层级对应关系:
    API返回的JSON结构层级为:{status: 200, data: {places: [Place对象数组]}},MyJson对应最外层结构,PlacesEntity对应data字段,Place对应数组中的单个对象,层级匹配即可正确解析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:53:13