‘List’ 不是类型 ‘Map‘ 的子类型。

huangapple go评论73阅读模式
英文:

'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:

  1. 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.
  }
});
  1. 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 &#39;package:flutter/material.dart&#39;; import &#39;package:flutter_localizations/flutter_localizations.dart&#39;; import &#39;package:http/http.dart&#39; as http; import &#39;dart:convert&#39; as convert; import &#39;package:flutter_application_1/Model/Currency.dart&#39;;
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(&#39;fa&#39;), // Persian ], theme: ThemeData( fontFamily: &quot;IranSans&quot;, textTheme: const TextTheme( displayLarge: TextStyle( fontFamily: &quot;IranSans&quot;, fontSize: 16, fontWeight: FontWeight.w700), bodyLarge: TextStyle( fontFamily: &quot;IranSans&quot;, fontSize: 13, fontWeight: FontWeight.w300), displayMedium: TextStyle( fontFamily: &quot;IranSans&quot;, fontSize: 14, color: Colors.white, fontWeight: FontWeight.w300))), debugShowCheckedModeBanner: false, home: HomePage(), ); } }
class HomePage extends StatefulWidget { HomePage({ super.key, });
@override State createState() =&gt; _HomePageState(); }
class _HomePageState extends State { List currency = [];
getResponse() { var url = &quot;http://api.navasan.tech/latest/?api_key=freeTFyHoFiXvgG6UNOlQHfehDasa7eK&quot;; http.get(Uri.parse(url)).then((value) { print(value.statusCode); if (value.statusCode == 200) { List jsonList = convert.jsonDecode(value.body); if (jsonList.length &gt; 0) { for (var i = 0; i &lt; jsonList.length; i++) { setState(() { currency.add(Currency( id: jsonList[i], value: jsonList[i][&quot;value&quot;], change: jsonList[i][&quot;change&quot;], timestamp: jsonList[i][&#39;timestamp&#39;], date: jsonList[i][&quot;date&quot;])); }); } } } }); }
@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(&quot;assets/images/currency.png&quot;), Align( alignment: Alignment.centerRight, child: Text(&quot;قیمت به روز ارز&quot;, style: Theme.of(context).textTheme.displayLarge), ), Expanded( child: Align( alignment: Alignment.centerLeft, child: Image.asset(&quot;assets/images/menu.png&quot;)), ), 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(&quot;assets/images/questionMark.png&quot;), const SizedBox( width: 8, ), Text(&quot;نرخ ارز آزاد چیست؟&quot;, style: Theme.of(context).textTheme.displayLarge), ], ), const SizedBox( height: 12, ), Text( &quot;مقصود از نرخ ارز آزاد، نرخ خرید و فروش ارز در بازار غیررسمی و غیردولتی است. از آنجایی که اغلب مبادلات عموم مردم در این بازار به انجام می رسد و دسترسی به آن برای همگان امکان پذیر است لذا این نرخ از بیشترین وجاهت و مقبولیت عمومی برخوردار است و محاسبات و مبادلات عمدتا بر مبنای آن صورت می پذیرد. &quot;, 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( &#39;نام آزاد ارز&#39;, style: Theme.of(context).textTheme.displayMedium, ), Text( &#39;قیمت&#39;, style: Theme.of(context).textTheme.displayMedium, ), Text( &#39;تغییر&#39;, 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&lt; RoundedRectangleBorder&gt;( RoundedRectangleBorder( borderRadius: BorderRadius.all( Radius.circular(100)), side: BorderSide( width: 1, color: Colors.deepPurpleAccent, ))), backgroundColor: MaterialStatePropertyAll( Color.fromARGB(255, 202, 193, 255))), onPressed: () =&gt; _showSnackBar( context, &quot;بروز رسانی با موفقیت انجام شد.&quot;), icon: const Icon( CupertinoIcons.refresh_bold, color: Colors.black, ), label: Padding( padding: const EdgeInsets.fromLTRB(8, 0, 0, 0), child: Text( &#39;بروز رسانی&#39;, style: Theme.of(context).textTheme.displayLarge, ), )), ), Text( &#39;آخرین بروز رسانی ${_getTime()}&#39;, style: Theme.of(context).textTheme.bodyLarge, ), const SizedBox( width: 8, ) ], ), ), ) ], ), ), )); }
String _getTime() { return &quot;20:45&quot;; } }
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( &#39;Advertisement&#39;, 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 : 
&quot;harat_naghdi_buy&quot;: { &quot;value&quot;: &quot;49970&quot;, &quot;change&quot;: -720, &quot;timestamp&quot;: 1678374494, &quot;date&quot;: &quot;1401-12-18 18:38:14&quot; }, &quot;harat_naghdi_sell&quot;: { &quot;value&quot;: &quot;49950&quot;, &quot;change&quot;: -790, &quot;timestamp&quot;: 1678374150, &quot;date&quot;: &quot;1401-12-18 18:32:30&quot; },

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 &gt; 0) {
    jsonList.forEach((key, value) {
      currency.add(Currency(
          id: jsonList[key],
          value: jsonList[key][&quot;value&quot;],
          change: jsonList[key][&quot;change&quot;],
          timestamp: jsonList[key][&#39;timestamp&#39;],
          date: jsonList[key][&quot;date&quot;]));
    });
    setState(() {});
  }
}

huangapple
  • 本文由 发表于 2023年3月10日 01:27:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75688067.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定