繁体   English   中英

类型列表<dynamic>不是 Map 的子类型<string,dynamic></string,dynamic></dynamic>

[英]type List<dynamic> is not a subtype of Map<String,dynamic>

我已经能够在 Flutter 上学习一些关于基本 UI 设计的教程,并且是 API 电话的新手。 我想我需要在调用 API 后转换类型,但我不知道如何转换。

注意:我知道一个文件中有很多代码,但我会将 API 调用文件和自定义 class 文件与我的主文件分开

import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Future<Country> fetchAlbum() async {
  final response = await http.get('https://restcountries.eu/rest/v2/all');

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    return Country.fromJson(json.decode(response.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load album');
  }
}

class Country {
  final String name;
  final List<String> topLevelDomain;
  final String alpha2Code;
  final String alpha3Code;
  final String callingCodes;
  final String capital;
  final String region;
  final String subregion;
  final int population;
  final List<int> latlng;
  final String demonym;
  final int area;
  final int gini;
  final List<String> timezones;
  final List<String> borders;
  final String nativeName;
  final int numericCode;
  final List<String> currencies;
  final List<String> translations;
  final String flag;
  final String cioc;

  Country({
    @required this.name,
    @required this.topLevelDomain,
    @required this.alpha2Code,
    @required this.alpha3Code,
    @required this.callingCodes,
    @required this.capital,
    @required this.region,
    @required this.subregion,
    @required this.population,
    @required this.latlng,
    @required this.demonym,
    @required this.area,
    @required this.gini,
    @required this.timezones,
    @required this.borders,
    @required this.nativeName,
    @required this.numericCode,
    @required this.currencies,
    @required this.translations,
    @required this.flag,
    @required this.cioc,
  });

  factory Country.fromJson(Map<String, dynamic> json) {
    return Country(
      name: json['name'],
      topLevelDomain: json['topLevelDomain'],
      alpha2Code: json['alpha2Code'],
      alpha3Code: json['alpha3Code'],
      callingCodes: json['callingCodes'],
      capital: json['capital'],
      region: json['region'],
      subregion: json['subregion'],
      population: json['population'],
      latlng: json['latlng'],
      demonym: json['demonym'],
      area: json['area'],
      gini: json['gini'],
      timezones: json['timezones'],
      borders: json['borders'],
      nativeName: json['nativeName'],
      numericCode: json['numericCode'],
      currencies: json['currencies'],
      translations: json['translations'],
      flag: json['flag'],
      cioc: json['cioc'],
    );
  }
}

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Future<Country> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = fetchAlbum();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Fetch Data Example'),
        ),
        body: Center(
          child: FutureBuilder<Country>(
            future: futureAlbum,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text(snapshot.data.name);
              } else if (snapshot.hasError) {
                return Text("${snapshot.error}");
              }

              // By default, show a loading spinner.
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}

这是我的模拟器屏幕的样子: http://i1.imgrr.com/18Z/7512_Screenshot1599026660.png

第 12 行'返回 Country.fromJson(json.decode(response.body));'

我认为'json.decode(response.body)'的类型是'List',但这里的参数类型是Map。 也许您的响应是国家/地区对象列表,但它返回 1 个国家/地区 object。这就是您收到此错误的原因

您的 API 返回List而不是Map

您需要将每个元素 map 作为一个Country

Future<List<Country>> fetchAlbum() async {
  final response = await http.get('https://restcountries.eu/rest/v2/all');

  if (response.statusCode == 200) {
     List<Country> countryList = ((json.decode(response.body) as List).map((i) => Country.fromJson(i)).toList();
    return countryList;
  } else {
    throw Exception('Failed to load album');
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM