我尝试从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"]);
}
}
'
1条答案
按热度按时间bqf10yzr1#
看起来你的
json["parsed"]
是空的,但是你试图调用其中的第一个条目,为了避免这种情况发生,你可以动态地解析你的列表,如下所示:字符串
然后将fetchAlbum更改为:
你还需要把你的
FutureBuilder
修改成: