Flutter - 无法将所有 json 数据从 api 响应保存到 Iterable List 编辑:(无法从可迭代列表中获取数据)

Posted

技术标签:

【中文标题】Flutter - 无法将所有 json 数据从 api 响应保存到 Iterable List 编辑:(无法从可迭代列表中获取数据)【英文标题】:Flutter - Can't save all json data to Iterable List from api response EDIT: ( Can't Fetch Data from iterable List) 【发布时间】:2020-04-21 00:04:01 【问题描述】:

我有一个返回一些数据的 api。我只需要从 api 获取菜数据。问题是当我从 api 响应中获取数据时,第一道菜数据只保存到 iteratable list

编辑

我无法从可迭代列表中获取数据

api如下所示

  [
  

    "restaurant_name": "Cafe",
    "restaurant_image": "http://restaurants.unicomerp.net/images/Restaurant/1010000001.jpg",
    "table_id": "1",
    "table_name": "Table 01",
    "branch_name": "Cafe",
    "nexturl": "http://snapittapp.snapitt.net/api/menu/10/?org=1010000001&branch_id=1000000001&limit=10&offset=20&lang=en",
    "table_menu_list": [
      
        "menu_category": "Salads and Soup",
        "menu_category_id": "11",
        "menu_category_image": "http://restaurants.unicomerp.net/images/Restaurant/Item/ItemGroup_11.jpg",
        "nexturl": "http://snapittapp.snapitt.net/api/menu/20/?org=1010000001&branch_id=1000000001&menuCat=11&limit=10&offset=20&lang=en",
        "category_dishes": [
          
            "dish_id": "100000001",
            "dish_name": "Spinach Salad",
            "dish_price": 7.95,
            "dish_image": "http://restaurants.unicomerp.net//images/Restaurant/1010000001/Item/Items/100000001.jpg",
            "dish_currency": "SAR",
            "dish_calories": 15,
            "dish_description": "Fresh spinach, mushrooms, and hard-boiled egg served with warm bacon vinaigrette",
            "dish_Availability": true,
            "dish_Type": 2,
            "nexturl": "http://snapittapp.snapitt.net/api/menu/30/?org=1010000001&branch_id=1000000001&menuItem=100000001&limit=10&offset=20&lang=en",
            "addonCat": [
              
                "addon_category": "Spicy/Non-Spicy",
                "addon_category_id": "104",
                "addon_selection": 0,
                "nexturl": "http://snapittapp.snapitt.net/api/menu/40/?org=1010000001&branch_id=1000000001&menuItem=100000001&menuAddonCat=104&menuAddonselc=0&limit=10&offset=20&lang=en",
                "addons": [
                  
                    "dish_id": "100000032",
                    "dish_name": "Non Spicy",
                    "dish_price": 25,
                    "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/Item/Item_100000025.jpg",
                    "dish_currency": "SAR",
                    "dish_calories": 15,
                    "dish_description": "Non Spicy",
                    "dish_Availability": true,
                    "dish_Type": 1
                  
                ]
              ,
              
                "addon_category": "Add On",
                "addon_category_id": "101",
                "addon_selection": 1,
                "nexturl": "http://snapittapp.snapitt.net/api/menu/40/?org=1010000001&branch_id=1000000001&menuItem=100000001&menuAddonCat=101&menuAddonselc=1&limit=10&offset=20&lang=en",
                "addons": [
                  
                    "dish_id": "100000020",
                    "dish_name": "fried onions",
                    "dish_price": 15,
                    "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/Item/Item_100000020.jpg",
                    "dish_currency": "SAR",
                    "dish_calories": 10,
                    "dish_description": "fried onions",
                    "dish_Availability": true,
                    "dish_Type": 2
                  
                ]
              
            ]
          ,
          
            "dish_id": "100000003",
            "dish_name": "Traditional New England Seafood Chowder",
            "dish_price": 12,
            "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/1010000001/Item/Items/100000003.jpg",
            "dish_currency": "SAR",
            "dish_calories": 30,
            "dish_description": "with clams, scallops, and shrimp,",
            "dish_Availability": true,
            "dish_Type": 1,
            "nexturl": "http://snapittapp.snapitt.net/api/menu/30/?org=1010000001&branch_id=1000000001&menuItem=100000003&limit=10&offset=20&lang=en",
            "addonCat": []
          ,
          
            "dish_id": "100000004",
            "dish_name": "Salad Bar Soup",
            "dish_price": 5,
            "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/1010000001/Item/Items/100000004.jpg",
            "dish_currency": "SAR",
            "dish_calories": 30,
            "dish_description": "Flour Mixed with fresh green leafy vegetables",
            "dish_Availability": true,
            "dish_Type": 2,
            "nexturl": "http://snapittapp.snapitt.net/api/menu/30/?org=1010000001&branch_id=1000000001&menuItem=100000004&limit=10&offset=20&lang=en",
            "addonCat": []
          ,
          
            "dish_id": "100000005",
            "dish_name": "chicken-soup",
            "dish_price": 14.89,
            "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/1010000001/Item/Items/100000005.jpg",

            "dish_id": "100000029",
            "dish_name": "Tacos",
            "dish_price": 25,
            "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/Item/Item_100000029.jpg",
            "dish_currency": "SAR",
            "dish_calories": 225,
            "dish_description": "Mexican Street Tacos",
            "dish_Availability": true,
            "dish_Type": 3,
            "nexturl": "http://snapittapp.snapitt.net/api/menu/30/?org=1010000001&branch_id=1000000001&menuItem=100000029&limit=10&offset=20&lang=en",
            "addonCat": []
          
        ]
      
    ]
  
]

api中有一个名为addonCat的数据类别,我需要在从响应中获取数据时忽略它并继续下一道菜。

api_model.dart 这是我从 api 的响应中获取数据的地方

class CategoryDishes 
  final String dishId;
  final String dishName;
  final double dishPrice;
  final String dishImage;
  final String dishCurrency;
  final double dishCalories;
  final String dishDescription;
  final bool dishAvailability;
  final double dishType;
  final String nexturl;

  //final List<AddonCat> _addonCat;

  CategoryDishes(
      this.dishId,
      this.dishName,
      this.dishPrice,
      this.dishImage,
      this.dishCurrency,
      this.dishCalories,
      this.dishDescription,
      this.dishAvailability,
      this.dishType,
      this.nexturl);

  factory CategoryDishes.fromJson(Map<String, dynamic> json) 
    return CategoryDishes(
        dishId: json['dish_id'],
        dishName: json['dish_name'],
        dishPrice: json['dish_price'].toDouble(),
        dishImage:
            json['dish_image'] ?? Constants.FOOD_PLACEHOLDER_IMAGE_ASSET_URL,
        dishCurrency: json['dish_currency'],
        dishCalories: json['dish_calories'].toDouble(),
        dishDescription: json['dish_description'],
        dishAvailability: json['dish_Availability'],
        dishType: json['dish_Type'].toDouble(),
        nexturl: json['nexturl']);
  

  static Resource<List<CategoryDishes>> get all 
    return Resource(
        url: Constants.FOOD_API_URL,
        parse: (response) 
          final result = json.decode(response.body.toString());
          //  print(response);
          Iterable list = result[0]['table_menu_list'][0]['category_dishes'];
          debugPrint("=========== Dish_List ==============\n" + list.toString());
          debugPrint("====================================");
          return list.map((model) => CategoryDishes.fromJson(model)).toList();
        );
  

web.service.dart

class Resource<T> 
  final String url;
  T Function(Response response) parse;

  Resource(this.url, this.parse);


class Webservice 
  Future<T> load<T>(Resource<T> resource) async 
    final response = await http.get(resource.url);
    if (response.statusCode == 200) 
     // debugPrint("------D------>\n" + response.body);
      return resource.parse(response);
     else 
      throw Exception('Failed to load data!');
    
  

ma​​in.dart

https://pastebin.com/NuDKYCCD

现在我可以将数据保存到可迭代列表中,但无法从列表中获取数据到卡片元素。 main.dart上方是我获取数据的地方。

如何做到这一点?

编辑

我只能在api中获取dishlist的第一部分,在第一类之后有很多菜品,我需要获取所有菜品并显示到相应的标签,请参阅上面的 api 链接以了解 api 是如何的。

任何建议都会有所帮助。

【问题讨论】:

【参考方案1】:

它实际上是在保存数据。但是在使用debugPrint 时,它不会在控制台上打印。

您必须在debugPrint 中提供wrapWidth,这样您才能看到存储在变量中的完整响应。

debugPrint(
  "=========== Dish_List ==============\n" + list.toString(),
  wrapWidth: 1000,
);
debugPrint("====================================");

我认为这是您面临的问题。

你也可以做漂亮的打印以使其易于理解

debugPrint(
  "=========== Dish_List ==============",
);
JsonEncoder encoder = new JsonEncoder.withIndent('  ');
debugPrint('$encoder.convert(list)', wrapWidth: 1000);
debugPrint("====================================");

【讨论】:

@AllwiN 很高兴有帮助。我还用漂亮的字体更新了我的答案。你可以检查一下。 当我试图将数据提取到我的卡片元素时,仍然没有显示任何内容?我究竟做错了什么。这是main.dartpastebin.com/NuDKYCCD,这里我正在获取卡片元素的值。 @AllwiN 我会尝试找出问题所在。但您可能想要更改问题或创建新帖子。以便其他人也可以帮助您。 @AllwiN 我不确定问题出在哪里。但是您可以参考此代码GitHub 我面临一个问题,我无法从api 响应中获取所有数据。只有第一个名为 dish 的数组只有我可以从响应中获取。如何从api中获取所有菜肴?代码与我在问题中发布的代码保持一致。【参考方案2】:

列出所有菜肴

Container(
            color: Colors.white,
            padding: EdgeInsets.fromLTRB(5, 10, 5, 10),
            child: ListView.builder(
            itemCount:  apiResponse[0]['table_menu_list'][0]['category_dishes'].length,
              itemBuilder:(cc,ind)
                return ListTile(
                title:Text(apiResponse[0]['table_menu_list'][0]['category_dishes'][ind]['dish_name'])
                  //use other properties as your requirement
                );
              
            ))

从网络获取日期。我使用本地分配数据!换成自己的方法

void assignData()
    apiResponse = [
  

    "restaurant_name": "Cafe",
    "restaurant_image": "http://restaurants.unicomerp.net/images/Restaurant/1010000001.jpg",
    "table_id": "1",
    "table_name": "Table 01",
    "branch_name": "Cafe",
    "nexturl": "http://snapittapp.snapitt.net/api/menu/10/?org=1010000001&branch_id=1000000001&limit=10&offset=20&lang=en",
    "table_menu_list": [
      
        "menu_category": "Salads and Soup",
        "menu_category_id": "11",
        "menu_category_image": "http://restaurants.unicomerp.net/images/Restaurant/Item/ItemGroup_11.jpg",
        "nexturl": "http://snapittapp.snapitt.net/api/menu/20/?org=1010000001&branch_id=1000000001&menuCat=11&limit=10&offset=20&lang=en",
        "category_dishes": [
          
            "dish_id": "100000001",
            "dish_name": "Spinach Salad",
            "dish_price": 7.95,
            "dish_image": "http://restaurants.unicomerp.net//images/Restaurant/1010000001/Item/Items/100000001.jpg",
            "dish_currency": "SAR",
            "dish_calories": 15,
            "dish_description": "Fresh spinach, mushrooms, and hard-boiled egg served with warm bacon vinaigrette",
            "dish_Availability": true,
            "dish_Type": 2,
            "nexturl": "http://snapittapp.snapitt.net/api/menu/30/?org=1010000001&branch_id=1000000001&menuItem=100000001&limit=10&offset=20&lang=en",
            "addonCat": [
              
                "addon_category": "Spicy/Non-Spicy",
                "addon_category_id": "104",
                "addon_selection": 0,
                "nexturl": "http://snapittapp.snapitt.net/api/menu/40/?org=1010000001&branch_id=1000000001&menuItem=100000001&menuAddonCat=104&menuAddonselc=0&limit=10&offset=20&lang=en",
                "addons": [
                  
                    "dish_id": "100000032",
                    "dish_name": "Non Spicy",
                    "dish_price": 25,
                    "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/Item/Item_100000025.jpg",
                    "dish_currency": "SAR",
                    "dish_calories": 15,
                    "dish_description": "Non Spicy",
                    "dish_Availability": true,
                    "dish_Type": 1
                  
                ]
              ,
              
                "addon_category": "Add On",
                "addon_category_id": "101",
                "addon_selection": 1,
                "nexturl": "http://snapittapp.snapitt.net/api/menu/40/?org=1010000001&branch_id=1000000001&menuItem=100000001&menuAddonCat=101&menuAddonselc=1&limit=10&offset=20&lang=en",
                "addons": [
                  
                    "dish_id": "100000020",
                    "dish_name": "fried onions",
                    "dish_price": 15,
                    "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/Item/Item_100000020.jpg",
                    "dish_currency": "SAR",
                    "dish_calories": 10,
                    "dish_description": "fried onions",
                    "dish_Availability": true,
                    "dish_Type": 2
                  
                ]
              
            ]
          ,
          
            "dish_id": "100000003",
            "dish_name": "Traditional New England Seafood Chowder",
            "dish_price": 12,
            "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/1010000001/Item/Items/100000003.jpg",
            "dish_currency": "SAR",
            "dish_calories": 30,
            "dish_description": "with clams, scallops, and shrimp,",
            "dish_Availability": true,
            "dish_Type": 1,
            "nexturl": "http://snapittapp.snapitt.net/api/menu/30/?org=1010000001&branch_id=1000000001&menuItem=100000003&limit=10&offset=20&lang=en",
            "addonCat": []
          ,
          
            "dish_id": "100000004",
            "dish_name": "Salad Bar Soup",
            "dish_price": 5,
            "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/1010000001/Item/Items/100000004.jpg",
            "dish_currency": "SAR",
            "dish_calories": 30,
            "dish_description": "Flour Mixed with fresh green leafy vegetables",
            "dish_Availability": true,
            "dish_Type": 2,
            "nexturl": "http://snapittapp.snapitt.net/api/menu/30/?org=1010000001&branch_id=1000000001&menuItem=100000004&limit=10&offset=20&lang=en",
            "addonCat": []
          ,
          
            "dish_id": "100000005",
            "dish_name": "chicken-soup",
            "dish_price": 14.89,
            "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/1010000001/Item/Items/100000005.jpg",

            "dish_id": "100000029",
            "dish_name": "Tacos",
            "dish_price": 25,
            "dish_image": "http://restaurants.unicomerp.net/images/Restaurant/Item/Item_100000029.jpg",
            "dish_currency": "SAR",
            "dish_calories": 225,
            "dish_description": "Mexican Street Tacos",
            "dish_Availability": true,
            "dish_Type": 3,
            "nexturl": "http://snapittapp.snapitt.net/api/menu/30/?org=1010000001&branch_id=1000000001&menuItem=100000029&limit=10&offset=20&lang=en",
            "addonCat": []
          
        ]
      
    ]
  
];
  

截图

【讨论】:

谢谢老兄!!..让我试试这个。 cc 和 ind ---> 上下文和索引?? 这不起作用。问题是数据没有存储到可迭代列表中。 使用 List 而不是 iterable 列表 tmpList = apiResponse[0]['table_menu_list'][0]['category_dishes'];然后按索引获取【参考方案3】:

问题在于,您只对结果和 table_menu_list 中的第一项执行此操作


  static Resource<List<CategoryDishes>> get all 
    return Resource(
        url: Constants.FOOD_API_URL,
        parse: (response) 
          final result = json.decode(response.body.toString());
          //  print(response);
          Iterable list = result[0]['table_menu_list'][0]['category_dishes'];
          debugPrint("=========== Dish_List ==============\n" + list.toString());
          debugPrint("====================================");
          return list.map((model) => CategoryDishes.fromJson(model)).toList();
        );
  

解析函数我会这样做

final result = json.decode(response.body.toString());
          //  print(response);
List<CategoryDishes> list = []
List.from(result).forEach((item) =>
List.from(item['table_menu_list']).forEach((menuItem) => 
  List.from(menuItem['category_dishes']).forEach((dish) => 
   list.add(CategoryDishes.fromJson(dish))
)
)
);
debugPrint("=========== Dish_List ==============\n" + list.toString());
debugPrint("====================================");
return list;

如果您不想在列表中有重复的菜肴(具有相同 id 的菜肴),您可以使用地图

final result = json.decode(response.body.toString());
          //  print(response);
Map<String, CategoryDishes> map = 
List.from(result).forEach((item) =>
List.from(item['table_menu_list']).forEach((menuItem) => 
  List.from(menuItem['category_dishes']).forEach((dish) => 
   map[dish['dish_id']] = CategoryDishes.fromJson(dish);
)
)
);
return map.values.toList();

【讨论】:

谢谢。现在我在屏幕上获取所有菜肴数据。

以上是关于Flutter - 无法将所有 json 数据从 api 响应保存到 Iterable List 编辑:(无法从可迭代列表中获取数据)的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Documentsnapshot 映射到 Flutter 中的 Json 对象

在flutter中获取JSON数据返回NULL

在 Flutter 中,我如何使用 API 和 GetX 在 JSON 中获取数据

Flutter DistanceMatrix JSON 无法正确解析

Flutter 从本地化 JSON 文件解析数组

Flutter Hive:处理复杂 json 的多个类