无法将 JSON 响应映射到 Flutter 中的类对象

问题描述 投票:0回答:1

这是另一个“期望‘Map’类型的值,但得到‘List’类型之一”的问题。我搜索了几篇关于该主题的 Stack Overflow 帖子,包括以下内容:

我也尝试遵循这个 Flutter 食谱示例

所以,我想简单地调用一个返回 JSON 列表列表的 API。 这些内部字符串列表中的每一个都对应于我在下面定义的一个类对象,称为“Provider”。我已经创建了类工厂方法来将 JSON 映射到我的“Provider”类:

  • factory Provider.fromJsonMap(Map<String, dynamic> json)   # The preferred way to call
  • factory Provider.fromJsonListDynamic(List<dynamic> json)

我更喜欢使用第一个工厂方法,而不是第二个,因为我想通过名称引用每个字符串,而不是像您将在代码中看到的数组索引。

更新:

正如 @OmiShah 指出的,我从 Python API 传回的序列化 JSON 没有模式,因此我的反序列化 JSON 响应不包含有关数据的信息。所以我无法像这样引用数据:

json["name"]

因此,我更改了 Python API 以序列化强类型类对象列表,并将其作为 JSON 传递回 flutter。 以下是该数据在传回 flutter 之前在 Python 中的样子:

[
    Provider(name='Google Translate API', id='google.translate_api.v3', img_url='ggl.png'),
    Provider(name='Microsoft Translator', id='microsoft.translator.v3', img_url='mcs.png'),
    Provider(name='Amazon Translate API', id='amazon.translate.api.v2', img_url='aws.png'),
]

这就是数据经过 flutter 反序列化后的样子:

final List<dynamic> listProviders = jsonDecode(response.body);

// contents of listProviders
[
    "Provider(name='Google Translate API', id='google.translate_api.v3', img_url='ggl.png')",
    "Provider(name='Microsoft Translator', id='microsoft.translator.v3', img_url='mcs.png')",
    "Provider(name='Amazon Translate API', id='amazon.translate.api.v2', img_url='aws.png')",
]

然后我将其转换为地图列表(listMap),然后尝试将每个对象映射到我的“Provider”类对象(providerMap),最后将providerMap转换为列表:

final List<dynamic> listProviders = jsonDecode(response.body);
final List<Map<String, dynamic>> listMap = listProviders.cast<Map<String, dynamic>>();
var providerMap = listMap.map<Provider>((json) => Provider.fromJsonMap(json));
List<Provider> providers = providerMap.toList();

当我尝试将其转换为列表时,出现以下错误:

Error: Expected a value of type 'Map<String, dynamic>', but got one of type 'String'

我对 Flutter 还比较陌生。我想将数据作为强类型对象传递,并且我想以一种有意义的方式进行操作。

我创建的自定义类对象:

class Provider
{
    final String name;
    final String id;
    final String imageUrl;

    Provider( {required this.name, required this.id, required this.imageUrl });

    // Calling this function fails 
    factory Provider.fromJsonMap(Map<String, dynamic> json)
    {
        Provider provider = Provider
        (           
            name:     json["name"]     as String,
            id:       json["id"]       as String,
            imageUrl: json["imageUrl"] as String,
        );

        return provider;
    }

    // Calling this function works
    factory Provider.fromJsonListDynamic(List<dynamic> json)
    {
        Provider provider = Provider
        (
            name:     json[0] as String,
            id:       json[1] as String,
            imageUrl: json[2] as String,
        );

        return provider;
    }
}

它在 PageState 类中的 Future 异步函数中被调用:

class _DetectorPageState extends State<DetectorPage>
{
    ...

    Future<List<Provider>> getMtProviders() async 
    {
        Uri url = Uri.parse(SOME_API_URL);
        http.Response response = await http.get(url);

        if (response.statusCode == 200) 
        {
            // THIS CODE DOES NOT WORK
            final List<dynamic> listProviders = jsonDecode(response.body);
            final List<Map<String, dynamic>> listMap = listProviders.cast<Map<String, dynamic>>();
            var providerMap = listMap.map<Provider>((json) => Provider.fromJsonMap(json));
            List<Provider> providers = providerMap.toList();
        
            // THIS CODE WORKS
            // List<dynamic> listProviders = jsonDecode(response.body);
            // List<Provider> providers = listProviders.map((provider) => Provider.fromJsonListDynamic(provider as List<dynamic>)).toList();

            return providers;
        } 
        else 
        {
            print('Request failed with status: ${response.statusCode}.');
            return [];
        }
    }
}
json flutter http-get
1个回答
1
投票

问题出在我的 python API 中的 JSON 序列化。我需要序列化包含我的数据的字典对象列表,而不是序列化自定义类对象列表。

providers_dict = \   # Sample Data
[
    {"name": "Google Translate API", "id": "google.translate_api.v3", "img_url": "ggl_translate.png"},
    {"name": "Microsoft Translator", "id": "microsoft.translator.v3", "img_url": "mcs_translate.png"},
    {"name": "Amazon Translate API", "id": "amazon.translate.api.v2", "img_url": "aws_translate.png"},
]

然后调用 json.dumps 方法将数据序列化为 JSON,如下所示:

providers_json = json.dumps(providers_dict)
return providers_json
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.