Flutter调用Laravel API报错NoSuchMethodError: int无[]方法
问题:Flutter调用Laravel API转换列表时出现NoSuchMethodError错误
尝试通过Laravel API获取MySQL数据并转换为Flutter列表,返回错误:NoSuchMethodError: Class 'int' has no instance method '[]',错误详情显示接收者为1,尝试调用["idAnunFr"]。
错误信息
I/flutter ( 8481): NoSuchMethodError: Class 'int' has no instance method '[]'. I/flutter ( 8481): Receiver: 1 I/flutter ( 8481): Tried calling: []("idAnunFr")
Provider代码(含forEach逻辑)
import 'package:bicos_app/model/anuncio_Freelancer.dart'; import 'package:bicos_app/model/freelancer.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:intl/intl.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../utils/freelancer_preferences.dart'; import '../utils/user_preferences.dart'; class AnunFreelancerProvider with ChangeNotifier { late Freelancer freelancer; List<AnuncioFreelancer> _anunciosMyFreelancer = []; List<AnuncioFreelancer> getAnunciosMyFreelancer() => _anunciosMyFreelancer; Future<dynamic> loadAnunMyFreelancer(int id) async { try { _anunciosMyFreelancer.clear(); var response = await Dio() .get('http://10.0.2.2:8000/api/getAnunFreelancerByFreelancer/$id'); if (response.data['status'] == '200') { response.data['anuncios'].forEach( (k, e) { AnuncioFreelancer anuncio = AnuncioFreelancer( idAnunFr: e['idAnunFr'], TituloAnunFr: e['TituloAnunFr'], DescAnunFr: e['DescAnunFr'], PrecoAnunFr: e['PrecoAnunFr'], ImgAnunFr: e['ImgAnunFr'], StatusAnunFr: e['StatusAnunFr'], DataAnunFr: e['DataAnunFr'], idFrAnunFr: e['idFrAnunFr'], idTipoServAnunFr: e['idTipoServAnunFr'], ); if (anuncio.StatusAnunFr == '1') { if (_anunciosMyFreelancer .any((element) => element.idAnunFr == anuncio.idAnunFr)) { print('_'); } else { _anunciosMyFreelancer.add(anuncio); } } }, ); } else { print(response.data['message'].toString()); } notifyListeners(); } catch (e) { print(e); } } }
模型代码
class AnuncioFreelancer { final int idAnunFr; final String TituloAnunFr; final String DescAnunFr; final double PrecoAnunFr; final String ImgAnunFr; final String StatusAnunFr; final String DataAnunFr; final int idFrAnunFr; final int idTipoServAnunFr; const AnuncioFreelancer({ required this.idAnunFr, required this.TituloAnunFr, required this.DescAnunFr, required this.PrecoAnunFr, required this.ImgAnunFr, required this.StatusAnunFr, required this.DataAnunFr, required this.idFrAnunFr, required this.idTipoServAnunFr, }); }
Laravel API控制器代码
Dio.get调用的方法:
public function getAnunFreelancerByFreelancer($idFrAnunFr) { if(TblAnunFreelancer::where('idFrAnunFr', $idFrAnunFr)->exists()) { $anunfr = TblAnunFreelancer::find($idFrAnunFr); return response()->json([ 'status'=>'200', 'anuncios'=>$anunfr, ]); } else { return response()->json([ 'status'=>'400', 'message'=>'Você não possui anúncios', ]); } }
期望的response.data示例
{ "idAnunFr": 1, "TituloAnunFr": "Title", "DescAnunFr": "Description", "PrecoAnunFr": 200.00, "ImgAnunFr": "assets/images/testeImagemAnun.png", "StatusAnunFr": "1", "DataAnunFr": "2022-11-27", "idFrAnunFr": 1, "idTipoServAnunFr": 1 }
问题分析与解决方案
核心问题
Laravel API返回数据格式错误:
- 控制器中
TblAnunFreelancer::find($idFrAnunFr)是根据表主键查询单条记录,但需求是获取所有idFrAnunFr匹配的记录,导致返回单个对象而非数组。 exists()判断的是where('idFrAnunFr', $idFrAnunFr)有结果,但find()用主键查询,逻辑不匹配,返回数据不符合预期。
- 控制器中
Flutter端处理逻辑错误:
- Flutter代码用
response.data['anuncios'].forEach((k, e) {...})遍历键值对,但API返回单个对象时,k是属性名、e是属性值(比如1),调用e['idAnunFr']时,e是int类型,触发错误。
- Flutter代码用
修复步骤
1. 修正Laravel API控制器代码
改为获取所有匹配idFrAnunFr的记录,返回数组:
public function getAnunFreelancerByFreelancer($idFrAnunFr) { $anunfr = TblAnunFreelancer::where('idFrAnunFr', $idFrAnunFr)->get(); if($anunfr->isNotEmpty()) { return response()->json([ 'status'=>'200', 'anuncios'=>$anunfr, ]); } else { return response()->json([ 'status'=>'400', 'message'=>'Você não possui anúncios', ]); } }
- 使用
where()->get()获取所有符合条件的记录,返回集合(转JSON后为数组)。 - 用
isNotEmpty()判断数据存在性,逻辑更统一。
2. 修正Flutter端遍历逻辑
适配API返回的数组格式,改用数组遍历方式:
if (response.data['status'] == '200') { // 遍历数组中的单条广告数据 for (var e in response.data['anuncios']) { AnuncioFreelancer anuncio = AnuncioFreelancer( idAnunFr: e['idAnunFr'], TituloAnunFr: e['TituloAnunFr'], DescAnunFr: e['DescAnunFr'], // 处理数值类型转换,避免类型不匹配 PrecoAnunFr: double.parse(e['PrecoAnunFr'].toString()), ImgAnunFr: e['ImgAnunFr'], StatusAnunFr: e['StatusAnunFr'], DataAnunFr: e['DataAnunFr'], idFrAnunFr: e['idFrAnunFr'], idTipoServAnunFr: e['idTipoServAnunFr'], ); if (anuncio.StatusAnunFr == '1') { if (!_anunciosMyFreelancer.any((element) => element.idAnunFr == anuncio.idAnunFr)) { _anunciosMyFreelancer.add(anuncio); } } } }
- 用
for (var e in ...)遍历数组,每个e为单条广告对象,可直接通过e['key']获取属性。 - 增加
PrecoAnunFr的类型转换,避免数据库返回数值类型不匹配的问题。
额外建议
- Flutter中可使用
json_serializable库自动生成模型序列化/反序列化代码,减少手动解析错误。 - Laravel中建议统一返回格式,比如状态码使用数字类型,更符合RESTful规范。
内容的提问来源于stack exchange,提问作者munized by cg
相关产品推荐
相关产品推荐

