Flutter,无法提取 api 数据:(未处理的异常:NoSuchMethodError:方法 'map' 在 null 上被调用。)

Posted

技术标签:

【中文标题】Flutter,无法提取 api 数据:(未处理的异常:NoSuchMethodError:方法 \'map\' 在 null 上被调用。)【英文标题】:Flutter, can't extract api data : (Unhandled Exception: NoSuchMethodError: The method 'map' was called on null.)Flutter,无法提取 api 数据:(未处理的异常:NoSuchMethodError:方法 'map' 在 null 上被调用。) 【发布时间】:2022-01-16 01:39:28 【问题描述】:

我想从这个 api 获取几个 JSON 数据:www.themealdb.com,它使用了一些类。我在类别类别上取得了成功,但在主要课程“膳食”上却没有成功。 我的调试控制台上有这个错误:

    [VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: NoSuchMethodError: The method 'map' was called on null.
Receiver: null
Tried calling: map<Meal>(Closure: (dynamic) => Meal)
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:63:5)
#1      MealDBApi.featchMeal
package:gang_de_recettes/services/mealDB_api.dart:27
<asynchronous suspension>
#2      BlocMeal.fetchMealsByLetter
package:gang_de_recettes/blocs/bloc_meal.dart:17
<asynchronous suspension>

在反序列化 JSON 对象方面,我是新手(这是我的第一个问题),因此感谢您对此提供的帮助。

(我也使用 BLoC 模式,但与我的问题无关)

这是我的 JSON 文件 pb 的一部分(或:https://www.themealdb.com/api/json/v1/1/search.php?f=a)

"meals":["idMeal":"52768","strMeal":"Apple Frangipan Tart","strDrinkAlternate":null,"strCategory":"Dessert","strArea":"British","strInstructions":"Preheat the oven to 200C\/180C Fan\/Gas 6.\r\nPut the biscuits in a large re-sealable freezer bag and bash with a rolling pin into fine crumbs. Melt the butter in a small pan, then add the biscuit crumbs and stir until coated with butter. Tip into the tart tin and, using the back of a spoon, press over the base and sides of the tin to give an even layer. Chill in the fridge while you make the filling.\r\nCream together the butter and sugar until light and fluffy. You can do this in a food processor if you have one. Process for 2-3 minutes. Mix in the eggs, then add the ground almonds and almond extract and blend until well combined.\r\nPeel the apples, and cut thin slices of apple. Do this at the last minute to prevent the apple going brown. Arrange the slices over the biscuit base. Spread the frangipane filling evenly on top. Level the surface and sprinkle with the flaked almonds.\r\nBake for 20-25 minutes until golden-brown and set.\r\nRemove from the oven and leave to cool for 15 minutes. Remove the sides of the tin. An easy way to do this is to stand the tin on a can of beans and push down gently on the edges of the tin.\r\nTransfer the tart, with the tin base attached, to a serving plate. Serve warm with cream, cr\u00e8me fraiche or ice cream.","strMealThumb":"https:\/\/www.themealdb.com\/images\/media\/meals\/wxywrq1468235067.jpg","strTags":"Tart,Baking,Fruity","strYoutube":"https:\/\/www.youtube.com\/watch?v=rp8Slv4INLk","strIngredient1":"digestive biscuits","strIngredient2":"butter","strIngredient3":"Bramley apples","strIngredient4":"butter, softened","strIngredient5":"caster sugar","strIngredient6":"free-range eggs, beaten","strIngredient7":"ground almonds","strIngredient8":"almond extract","strIngredient9":"flaked almonds","strIngredient10":"","strIngredient11":"","strIngredient12":"","strIngredient13":"","strIngredient14":"","strIngredient15":"","strIngredient16":null,"strIngredient17":null,"strIngredient18":null,"strIngredient19":null,"strIngredient20":null,"strMeasure1":"175g\/6oz","strMeasure2":"75g\/3oz","strMeasure3":"200g\/7oz","strMeasure4":"75g\/3oz","strMeasure5":"75g\/3oz","strMeasure6":"2","strMeasure7":"75g\/3oz","strMeasure8":"1 tsp","strMeasure9":"50g\/1\u00beoz","strMeasure10":"","strMeasure11":"","strMeasure12":"","strMeasure13":"","strMeasure14":"","strMeasure15":"","strMeasure16":null,"strMeasure17":null,"strMeasure18":null,"strMeasure19":null,"strMeasure20":null,"strSource":null,"strImageSource":null,"strCreativeCommonsConfirmed":null,"dateModified":null,

我只想测试 id、name 和 image url 的用餐课程:

    class Meal 
  String idMeal;
  String strMeal;
  String strMealThumb;

  Meal(this.idMeal, this.strMeal, this.strMealThumb);

  Meal.fromJson(Map<String, dynamic> json)
      : idMeal = json["idMeal"],
        strMeal = json["strMeal"],
        strMealThumb = json["strMealThumb"];

  Map<String, dynamic> toJson() => 
        'idMeal': idMeal,
        'strMeal': strMeal,
        'strMealThumb': strMealThumb,
      ;

我的http请求文件:

import 'dart:developer';

import 'package:gang_de_recettes/model/category.dart';
import 'package:gang_de_recettes/model/meal.dart';
import 'package:http/http.dart' as http;
import 'dart:convert' show json;

class MealDBApi 
  final _baseUrl = "https://www.themealdb.com/api/json/v1/1/";


  String _mealQueryBy1stLetter() => _baseUrl + "search.php?f=" + "a";
  String _allCategories() => _baseUrl + "categories.php";

  Future<List<dynamic>> request(String urlString, String key) async 
    var uri = Uri.parse(urlString);
    final result = await http.get(uri);
    final body = json.decode(result.body);
    //print("body :  ");
    //log(body.toString());
    return body[key];
  

  Future<List<Meal>> featchMeal() async 
    List<dynamic> list = await request(_mealQueryBy1stLetter(), "");
    //print("listmeals : $list");
    return list.map((json) => Meal.fromJson(json)).toList();
  

  Future<List<Category>> fetchCategory() async 
    final List<dynamic> list = await request(_allCategories(), "categories");
    print("listctgry : $list");
    return list.map((json) => Category.fromJson(json)).toList();
  

还有我的集团(但正如我所说,这可能不相关):

import 'dart:async';

import 'package:gang_de_recettes/bloc/bloc.dart';
import 'package:gang_de_recettes/model/meal.dart';
import 'package:gang_de_recettes/services/mealDB_api.dart';

class BlocMeal extends Bloc 
  final _streamController = StreamController<List<Meal>>();
  Stream<List<Meal>> get stream => _streamController.stream;
  Sink<List<Meal>> get sink => _streamController.sink;

  BlocMeal() 
    fetchMealsByLetter();
  

  fetchMealsByLetter() async 
    final meals = await MealDBApi().featchMeal();
    sink.add(meals);
  


  @override
  dispose() => _streamController.close();

正如我之前所说,所有这些都适用于类类别。

感谢您的帮助

【问题讨论】:

【参考方案1】:

我相信这里

List<dynamic> list = await request(_mealQueryBy1stLetter(), "");

list 将为空,因为您的地图没有键 "" 你可能想这样做

List<dynamic> list = await request(_mealQueryBy1stLetter(), "meals")

希望这是问题所在并解决了它

【讨论】:

以上是关于Flutter,无法提取 api 数据:(未处理的异常:NoSuchMethodError:方法 'map' 在 null 上被调用。)的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:快照未显示数据

Flutter未处理的异常:SocketException:操作系统错误:连接被拒绝,errno = 111

Flutter:未处理的异常:无法加载资产

Flutter 中的错误:未处理的异常:“Null”类型不是“String”类型的子类型

未处理的异常:类型“int”不是 Flutter 应用程序中“String”类型的子类型

从 Laravel API 服务器接收的数据未显示在 Flutter 屏幕上