英文:
'List' is not a subtype of type 'Map<String, dynamic>'
问题
I see that you're encountering a type error in your Flutter app. The error message you're getting, "Flutter 'List' is not a subtype of type 'Map<String, dynamic>'," indicates that there is a mismatch between the expected data type and the actual data you're trying to use.
It appears that you are trying to decode a JSON response from an API and map it to a List
. However, the API response seems to be a JSON object with key-value pairs, which should be decoded into a Map<String, dynamic>
, not a List
.
To fix this issue, you should update your code as follows:
- Update your API response parsing code to decode the JSON as a
Map<String, dynamic>
:
http.get(Uri.parse(url)).then((value) {
print(value.statusCode);
if (value.statusCode == 200) {
Map<String, dynamic> jsonResponse = convert.jsonDecode(value.body);
// Now you can access the data using keys, for example:
Map<String, dynamic> haratNaghdiBuy = jsonResponse["harat_naghdi_buy"];
// You can then extract values like this:
String value = haratNaghdiBuy["value"];
int change = haratNaghdiBuy["change"];
// Continue with your data processing.
}
});
- Update your model class to match the expected structure of the data:
class Currency {
String? id;
String? value;
int? change;
int? timestamp;
String? date;
Currency({
required this.id,
required this.value,
required this.change,
required this.timestamp,
required this.date,
});
}
Make sure your model class matches the structure of the data you're extracting from the API response.
With these changes, you should be able to properly decode the JSON response and map it to your Currency
model.
英文:
import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:http/http.dart' as http; import 'dart:convert' as convert; import 'package:flutter_application_1/Model/Currency.dart';
void main() { runApp(const MyApp()); }
class MyApp extends StatelessWidget { const MyApp({super.key});
@override Widget build(BuildContext context) { return MaterialApp( localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [ Locale('fa'), // Persian ], theme: ThemeData( fontFamily: "IranSans", textTheme: const TextTheme( displayLarge: TextStyle( fontFamily: "IranSans", fontSize: 16, fontWeight: FontWeight.w700), bodyLarge: TextStyle( fontFamily: "IranSans", fontSize: 13, fontWeight: FontWeight.w300), displayMedium: TextStyle( fontFamily: "IranSans", fontSize: 14, color: Colors.white, fontWeight: FontWeight.w300))), debugShowCheckedModeBanner: false, home: HomePage(), ); } }
class HomePage extends StatefulWidget { HomePage({ super.key, });
@override State createState() => _HomePageState(); }
class _HomePageState extends State { List currency = [];
getResponse() { var url = "http://api.navasan.tech/latest/?api_key=freeTFyHoFiXvgG6UNOlQHfehDasa7eK"; http.get(Uri.parse(url)).then((value) { print(value.statusCode); if (value.statusCode == 200) { List jsonList = convert.jsonDecode(value.body); if (jsonList.length > 0) { for (var i = 0; i < jsonList.length; i++) { setState(() { currency.add(Currency( id: jsonList[i], value: jsonList[i]["value"], change: jsonList[i]["change"], timestamp: jsonList[i]['timestamp'], date: jsonList[i]["date"])); }); } } } }); }
@override Widget build(BuildContext context) { getResponse(); return Scaffold( backgroundColor: const Color.fromARGB(255, 243, 243, 243), appBar: AppBar( elevation: 0, backgroundColor: Colors.white, actions: [ const SizedBox( width: 12, ), Image.asset("assets/images/currency.png"), Align( alignment: Alignment.centerRight, child: Text("قیمت به روز ارز", style: Theme.of(context).textTheme.displayLarge), ), Expanded( child: Align( alignment: Alignment.centerLeft, child: Image.asset("assets/images/menu.png")), ), const SizedBox( width: 12, ), ], ), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(28.0), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset("assets/images/questionMark.png"), const SizedBox( width: 8, ), Text("نرخ ارز آزاد چیست؟", style: Theme.of(context).textTheme.displayLarge), ], ), const SizedBox( height: 12, ), Text( "مقصود از نرخ ارز آزاد، نرخ خرید و فروش ارز در بازار غیررسمی و غیردولتی است. از آنجایی که اغلب مبادلات عموم مردم در این بازار به انجام می رسد و دسترسی به آن برای همگان امکان پذیر است لذا این نرخ از بیشترین وجاهت و مقبولیت عمومی برخوردار است و محاسبات و مبادلات عمدتا بر مبنای آن صورت می پذیرد. ", textAlign: TextAlign.justify, textDirection: TextDirection.rtl, style: Theme.of(context).textTheme.bodyLarge, ), Padding( padding: const EdgeInsets.fromLTRB(0, 24, 0, 0), child: Container( width: double.infinity, height: 35, decoration: const BoxDecoration( color: Color.fromARGB(255, 130, 130, 130), borderRadius: BorderRadius.all(Radius.circular(100))), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( 'نام آزاد ارز', style: Theme.of(context).textTheme.displayMedium, ), Text( 'قیمت', style: Theme.of(context).textTheme.displayMedium, ), Text( 'تغییر', style: Theme.of(context).textTheme.displayMedium, ) ], ), ), ), SizedBox( height: 350, width: double.infinity, child: ListView.separated( itemCount: currency.length, scrollDirection: Axis.vertical, physics: const BouncingScrollPhysics(), itemBuilder: (BuildContext context, int position) { return Padding( padding: const EdgeInsets.fromLTRB(0, 8, 0, 0), child: MyItem(position, currency), ); }, separatorBuilder: (BuildContext context, int index) { if (index % 9 == 0) { return const Padding( padding: EdgeInsets.fromLTRB(0, 8, 0, 0), child: Ad(), ); } else { return const SizedBox.shrink(); } }, ), ), Padding( padding: const EdgeInsets.fromLTRB(0, 12, 0, 0), child: Container( width: double.infinity, height: 50, decoration: const BoxDecoration( color: Color.fromARGB(255, 232, 232, 232), borderRadius: BorderRadius.all(Radius.circular(100)), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( height: 50, child: TextButton.icon( style: const ButtonStyle( shape: MaterialStatePropertyAll< RoundedRectangleBorder>( RoundedRectangleBorder( borderRadius: BorderRadius.all( Radius.circular(100)), side: BorderSide( width: 1, color: Colors.deepPurpleAccent, ))), backgroundColor: MaterialStatePropertyAll( Color.fromARGB(255, 202, 193, 255))), onPressed: () => _showSnackBar( context, "بروز رسانی با موفقیت انجام شد."), icon: const Icon( CupertinoIcons.refresh_bold, color: Colors.black, ), label: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 0, 0), child: Text( 'بروز رسانی', style: Theme.of(context).textTheme.displayLarge, ), )), ), Text( 'آخرین بروز رسانی ${_getTime()}', style: Theme.of(context).textTheme.bodyLarge, ), const SizedBox( width: 8, ) ], ), ), ) ], ), ), )); }
String _getTime() { return "20:45"; } }
void _showSnackBar(BuildContext context, String msg) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text( msg, style: Theme.of(context).textTheme.displayMedium, ), duration: const Duration(seconds: 3), behavior: SnackBarBehavior.floating, backgroundColor: Colors.green, showCloseIcon: true, dismissDirection: DismissDirection.up, closeIconColor: Colors.white, padding: const EdgeInsets.fromLTRB(5, 5, 15, 5), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(100))), )); }
class MyItem extends StatelessWidget { int position;
List currency; MyItem( this.position, this.currency, );
@override Widget build(BuildContext context) { return Container( height: 50, decoration: const BoxDecoration( boxShadow: [ BoxShadow( blurRadius: 1, color: Colors.grey, ) ], color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(100))), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text( currency[position].id!, style: Theme.of(context).textTheme.bodyLarge, ), Text( currency[position].value!, style: Theme.of(context).textTheme.bodyLarge, ), Text( currency[position].change.toString(), style: Theme.of(context).textTheme.bodyLarge, ) ], ), ); } }
class Ad extends StatelessWidget { const Ad({ super.key, });
@override Widget build(BuildContext context) { return Container( height: 50, decoration: const BoxDecoration( boxShadow: [ BoxShadow( blurRadius: 1, color: Colors.grey, ) ], color: Colors.deepPurpleAccent, borderRadius: BorderRadius.all(Radius.circular(100))), child: Center( child: Text( 'Advertisement', style: Theme.of(context).textTheme.displayMedium, ))); } }
model class:
Currency { String? id; String? value; int? change; int? timestamp; String? date; Currency({ required this.id, required this.value, required this.change, required this.timestamp, required this.date, }); }
API :
"harat_naghdi_buy": { "value": "49970", "change": -720, "timestamp": 1678374494, "date": "1401-12-18 18:38:14" }, "harat_naghdi_sell": { "value": "49950", "change": -790, "timestamp": 1678374150, "date": "1401-12-18 18:32:30" },
I'm building a Flutter app which fetches data from an Api,when I run the app here is the error I get : Flutter 'List' is not a subtype of type 'Map<String, dynamic>'. I believe the API is sort of map<string, dynamic> but I don't know how to bring it into the code. As I made a model for the api variables.
答案1
得分: 1
你的响应是 Map,而不是列表。你可以尝试像这样修改代码:
if (value.statusCode == 200) {
Map jsonList = convert.jsonDecode(value.body);
if (jsonList.length > 0) {
jsonList.forEach((key, value) {
currency.add(Currency(
id: jsonList[key],
value: jsonList[key]["value"],
change: jsonList[key]["change"],
timestamp: jsonList[key]['timestamp'],
date: jsonList[key]["date"]));
});
setState(() {});
}
}
英文:
You are getting Map as response, instead of list. You can try like
if (value.statusCode == 200) {
Map jsonList = convert.jsonDecode(value.body);
if (jsonList.length > 0) {
jsonList.forEach((key, value) {
currency.add(Currency(
id: jsonList[key],
value: jsonList[key]["value"],
change: jsonList[key]["change"],
timestamp: jsonList[key]['timestamp'],
date: jsonList[key]["date"]));
});
setState(() {});
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论