dart Flutter误差:未处理的异常:范围错误(索引):无效值:有效值范围为空:0

kulphzqa  于 2022-12-16  发布在  Flutter
关注(0)|答案(1)|浏览(149)

我尝试从API获取数据,虽然数据是为硬编码请求获取的,但我无法动态获取。
它给出以下错误:

E/flutter (11813): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: RangeError (index): Invalid value: Valid value range is empty: 0
E/flutter (11813): #0      List.[] (dart:core-patch/growable_array.dart:264:36)
E/flutter (11813): #1      new Album.fromJson (package:todoapp/models/apihandler.dart:34:32)
E/flutter (11813): #2      fetchAlbum (package:todoapp/models/apihandler.dart:13:18)
E/flutter (11813): <asynchronous suspension>

我的主屏幕代码是:

import 'package:flutter/material.dart';
import 'package:todoapp/constants.dart';
import 'package:todoapp/models/apihandler.dart';

class NutrientFact extends StatefulWidget {
  @override
  State<NutrientFact> createState() => _NutrientFactState();
}

class _NutrientFactState extends State<NutrientFact> {
  @override
  late String inputdata;

  // late Future<Album> futureAlbum;
  late double proteins = 0;

  late double carbs = 0;

  late double fibers = 0;

  late double fats = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Center(
              child: Text(
            'SelfTime',
            style: TextStyle(fontWeight: FontWeight.bold),
          )),
        ),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Expanded(
                child: TextField(
              textAlign: TextAlign.center,
              onChanged: (value) {
                inputdata = value;
              },
            )),
            FactEntry("Protein", proteins.toString()),
            FactEntry("Carbohydrates", carbs.toString()),
            FactEntry("Fats", fats.toString()),
            FactEntry("Fiber", fibers.toString()),
            GestureDetector(
              child: Container(
                alignment: Alignment.center,
                margin: EdgeInsets.only(top: 10),
                color: kBottomButtonColor,
                width: double.infinity,
                height: kBottomButtonHeight,
                child: Text(
                  "SEARCH",
                  style: TextStyle(fontWeight: FontWeight.w600, fontSize: 30),
                ),
              ),
              onTap: () {
                setState(() {
                  FutureBuilder<Album>(
                    future: fetchAlbum(ing: inputdata),
                    builder: (context, snapshot) {
                      if (snapshot.hasData) {
                        proteins = snapshot.data!.protein;
                        carbs = snapshot.data!.carb;
                        fats = snapshot.data!.fat;
                        fibers = snapshot.data!.fiber;
                        print(proteins);
                      } else if (snapshot.hasError) {
                        return Text('-----${snapshot.error}');
                      }
                      return CircularProgressIndicator();
                    },
                  );
                });
              },
            ),
          ],
        ));
  }
}

class FactEntry extends StatelessWidget {
  FactEntry(this.label, this.data);
  late String label;
  late String data;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
        child: Container(
          decoration: kContainerDecoration,
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Center(
                  child: Text(
                label,
                style: TextStyle(fontSize: 20),
              )),
              Center(child: Text(data, style: TextStyle(fontSize: 20)))
            ],
          ),
        ),
      ),
    );
  }
}

API处理程序为:

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

Future<Album> fetchAlbum({String ing = 'chicken'}) async {
  final response = await http.get(
    Uri.parse(
        "https://api.edamam.com//api//food-database//v2//parser?app_id=$api_id&app_key=$api_key&ingr=ing&nutrition-type=cooking"),
  );

  if (response.statusCode == 200) {
    return Album.fromJson(jsonDecode(response.body));
  } else {
    throw Exception('Failed to load album');
  }
}

class Album {
  final double carb;
  final double protein;
  final double fat;
  final double fiber;

  const Album({
    required this.carb,
    required this.protein,
    required this.fat,
    required this.fiber,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
        protein: json["parsed"][0]["food"]["nutrients"]["PROCNT"],
        fat: json["parsed"][0]["food"]["nutrients"]["FAT"],
        fiber: json["parsed"][0]["food"]["nutrients"]["CHOCDF"],
        carb: json["parsed"][0]["food"]["nutrients"]["FIBTG"]);
  }
}

'

bqf10yzr

bqf10yzr1#

看起来你的json["parsed"]是空的,但是你试图调用其中的第一个条目,为了避免这种情况发生,你可以动态地解析你的列表,如下所示:

factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
        protein: json["food"]["nutrients"]["PROCNT"],
        fat: json["food"]["nutrients"]["FAT"],
        fiber: json["food"]["nutrients"]["CHOCDF"],
        carb: json["food"]["nutrients"]["FIBTG"]);
  }

字符串
然后将fetchAlbum更改为:

Future<List<Album>> fetchAlbum({String ing = 'chicken'}) async {
  final response = await http.get(
    Uri.parse(
        "https://api.edamam.com//api//food-database//v2//parser?app_id=$api_id&app_key=$api_key&ingr=ing&nutrition-type=cooking"),
  );

  if (response.statusCode == 200) {
    
    return (jsonDecode(response.body)["parsed"] as List).map((e) => Album.fromJson(e)).toList();
  } else {
    throw Exception('Failed to load album');
  }
}

你还需要把你的FutureBuilder修改成:

FutureBuilder<List<Album>>(
    future: fetchAlbum(ing: inputdata),
    builder: (context, snapshot) {
      switch (snapshot.connectionState) {
        case ConnectionState.waiting:
          return CircularProgressIndicator();
        default:
          if (snapshot.hasError) {
            return Text('Error: ${snapshot.error}');
          } else {
            List<Album> data = snapshot.data ?? [];

            return ListView.builder(
              itemBuilder: (context, index) {
                proteins = data[index].protein;
                carbs = data[index].carb;
                fats = data[index].fat;
                fibers = data[index].fiber;

                print(proteins);
                return Column(children: [
                  Text('${data[index].protein ?? ""}'),
                ]);
              },
              itemCount: data.length,
            );
          }
      }
    },
  ),

相关问题