Dart开发中如何正确增删REST API的数组列表数据
REST API数组字段增删操作失效问题排查
问题现象
开发过程中对REST API返回数据中的字符串数组执行新增、删除字符串条目操作,功能始终无法正常生效,暂未定位到问题根源。
接口原始返回JSON数据
{ "hotels": [ { "image": "http://0.0.0.0:8080/uploads/users/IWpEqUWxUxbWsmIoYfUX/95024057775943965869.jpg", "bedPrice": "10", "roomPrice": "30", "rooms": "50", "ac": "yes", "address": "kaambo", "latitude": "43.0890", "laundry": "yes", "name": "jaabir", "location": "Bosaso", "details": "Hosbitaalka Sixa Garoowe waxa ka howlgali doona 23/06/2022 Dr. Ahmed Bashe (abu-shafi) (FCPS MRCS-UK) oo ka socda Hosbitalka Shaafi Muqdisho kuna takhasusay qalliimada LAPAROSCOPY-ga sida Xameetida,Uur-kujirta,Eernada,Burooyinka IWM. Dr-ku wuxuu si joogta ah u imanayaa bil kasta insha allah. Wac: 7747373, 5065444, 5065333.Hosbitaalka Sixa Garoowe waxa ka howlgali doona 23/06/2022 Dr. Ahmed Bashe (abu-shafi) (FCPS MRCS-UK) oo ka socda Hosbitalka Shaafi Muqdisho kuna takhasusay qalliimada LAPAROSCOPY-ga sida Xameetida,Uur-kujirta,Eernada,Burooyinka IWM. Dr-ku wuxuu si joogta ah u imanayaa bil kasta insha allah. Wac: 7747373, 5065444, 5065333.Hosbitaalka Sixa Garoowe waxa ka howlgali doona 23/06/2022 Dr. Ahmed Bashe (abu-shafi) (FCPS MRCS-UK) oo ka socda Hosbitalka Shaafi Muqdisho kuna takhasusay qalliimada LAPAROSCOPY-ga sida Xameetida,Uur-kujirta,Eernada,Burooyinka IWM. Dr-ku wuxuu si joogta ah u imanayaa bil kasta insha allah. Wac: 7747373, 5065444, 5065333.", "id": "456", "beds": "100", "internet": "yes", "fastfood": "yes", "longitude": "23.0890", "images": [ "http://0.0.0.0:8080/uploads/users/IWpEqUWxUxbWsmIoYfUX/95024057775943965869.jpg", "http://0.0.0.0:8080/uploads/users/IWpEqUWxUxbWsmIoYfUX/95024057775943965869.jpg", "http://0.0.0.0:8080/uploads/users/IWpEqUWxUxbWsmIoYfUX/95024057775943965869.jpg" ], "likedUsers": [ "HftAroebyiUhaKSmsyrc" ], "adress": "laanta hawada" } ] }
原有Dart业务实现代码
_likeUser()async{ String api = "http://0.0.0.0:8080/path=hotels/456"; // this list from previous page _data['likedUsers'].toList(); List<String> likes = widget.likedUsers as List<String>; if(widget.likedUser.contain(widget.currentUser){ setState((){ _isLiked = false;}); var likeRemoved = likes.remove(widget.currentUser); await http.patch(Uri.parse(api), body: json.encode(<String, Object>{ "likedUsers": [likeRemoved] }); }else{ var likeAdded = likes.add(widget.currentUser); await http.patch(Uri.parse(api), body: json.encode(<String, Object>{ "likedUsers": [likeAdded] }); setState((){ _isLiked = true; }); } }
代码错误点汇总
- 基础语法错误:
List的包含判断方法是contains,原代码拼写为contain;同时if判断条件缺少右括号,代码本身就无法正常编译运行 - 判断逻辑错误:原代码判断点赞状态用的是不存在的
widget.likedUser属性,应该从likes列表里判断是否包含当前用户ID - 方法返回值误用:
List.remove()返回值是布尔类型,代表删除操作是否执行成功,不是被删除的元素List.add()没有返回值(返回void),赋值得到的是null
原代码把这两个返回值塞进数组传给接口,相当于给likedUsers字段传了[true/false]或者[null]的错误数据,完全不是预期的用户ID列表
- 传参逻辑错误:PATCH更新数组字段时,需要传递修改完成后的完整数组,原代码只传了单个错误返回值包裹成的数组,会直接覆盖服务端存储的整个点赞用户列表
- 请求配置缺失:发送JSON格式的PATCH请求没有设置
Content-Type: application/json请求头,多数后端框架无法正确解析请求体内容 - 状态更新时序错误:删除操作分支先执行
setState更新前端状态,再发接口请求,一旦接口请求失败,前端展示状态和服务端存储数据会不一致 - 类型转换风险:直接用
as List<String>强转数据,如果原接口返回的数据类型不匹配会直接抛出运行时异常 - 接口路径存疑:原接口地址写的
path=hotels/456不符合常规REST接口路径规范,需要和后端确认实际接口地址是否正确
修复后可运行代码
_likeUser() async { // 请根据后端实际接口规则调整请求地址 String api = "http://0.0.0.0:8080/hotels/456"; // 做安全类型转换,避免强转导致的运行时异常 List<String> likes = List<String>.from(widget.likedUsers); bool isAlreadyLiked = likes.contains(widget.currentUser); try { if (isAlreadyLiked) { likes.remove(widget.currentUser); // 接口请求成功后再更新前端状态 final response = await http.patch( Uri.parse(api), headers: {"Content-Type": "application/json"}, // 传递修改完成后的完整点赞用户列表 body: json.encode({"likedUsers": likes}), ); if (response.statusCode == 200) { setState(() { _isLiked = false; }); } } else { likes.add(widget.currentUser); final response = await http.patch( Uri.parse(api), headers: {"Content-Type": "application/json"}, body: json.encode({"likedUsers": likes}), ); if (response.statusCode == 200) { setState(() { _isLiked = true; }); } } } catch (e) { // 可在此处添加操作失败的提示逻辑,比如弹出Toast告知用户操作失败 print("点赞操作执行异常: $e"); } }
内容的提问来源于stack exchange,提问作者abdifatah nour
相关产品推荐
相关产品推荐

