flutter Dart和JSON:未处理的异常:类型“List< dynamic>”不是类型转换中类型“Map〈String,dynamic>”的子类型

kuhbmx9i  于 2023-03-19  发布在  Flutter
关注(0)|答案(2)|浏览(169)

我尝试从服务器访问JSON响应,以便在屏幕上输出内容,但我一直收到错误消息:未处理的异常:类型'List'在类型转换中不是类型'Map〈String,dynamic〉'的子类型。我对Dart和Json总体上还是个新手,所以我不确定该从哪里解决这个问题。以下是我编写的代码:

import 'dart:convert';

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

import './user_credentials_struct.dart';

class Credentials with ChangeNotifier {
  List<Accounts> _items = [];

  List<Accounts> get items {
    return [..._items];
  }

  Future<void> fetchAccounts() async {
    final selectAccountUrl =
        Uri.parse('https://cs.csub.edu/~tesscuro/database/selectAccounts.php');
    try {
      final response = await http.get(selectAccountUrl);
      final receivedData = json.decode(response.body) as Map<String, dynamic>;
      final List<Accounts> loadedData = [];
      receivedData.forEach((accountID, data) {
        loadedData.add(
          Accounts(
            id: accountID,
            siteUrl: data['url'],
            password: data['password'],
            userName: data['username'],
          ),
        );
      });
      _items = loadedData;
      notifyListeners();
    } catch (error) {
      rethrow;
    }
  }
}

这是我得到的JSON响应的一个示例:

[{"cID":1,"url":"www.google.com","username":"test","password":"password"},{"cID":1,"url":"www.youtube.com","username":"test1","password":"password1"}]

我已经将参数类型从String改为int,并使用不同的示例重写了代码。我还更改了Map类型以尝试使其工作。

ffx8fchx

ffx8fchx1#

基本上,您的响应是返回List而不是Map,换句话说,您可以编写json.decode(response.body) as List<dynamic>。我的建议是,您可以使用https://app.quicktype.io/通过利用现有JSON来创建模型。

class Accounts {
  Accounts({
    required this.cId,
    required this.url,
    required this.username,
    required this.password,
  });

  int cId;
  String url;
  String username;
  String password;

  factory Accounts.fromJson(Map<String, dynamic> json) => Accounts(
        cId: json["cID"],
        url: json["url"],
        username: json["username"],
        password: json["password"],
      );

  Map<String, dynamic> toJson() => {
        "cID": cId,
        "url": url,
        "username": username,
        "password": password,
      };
}

现在,在fetchAccounts函数中,实现如下所示

Future<void> fetchAccounts() async {
    final selectAccountUrl = Uri.parse('https://cs.csub.edu/~tesscuro/database/selectAccounts.php');
    try {
      final response = await http.get(selectAccountUrl);
      final receivedData = json.decode(response.body);
      print(receivedData);
      final listOfData = List<Accounts>.from(receivedData.map((x) => Accounts.fromJson(x)));
      _items = listOfData;
      notifyListeners();
    } catch (error) {
      rethrow;
    }
  }

基本上,它会将响应数据转换为帐户列表。我希望这能解决您的困惑。

xfyts7mz

xfyts7mz2#

读取错误
类型'List<dynamic>'不是类型转换中类型'Map<String, dynamic>'的子类型
json响应是List,您应该使用

final receivedData = json.decode(response.body) as List<dynamic>;

然后你可以把它转换成Accounts对象,如下所示:

final loadedData = receivedData
      .map((json) => Accounts(
          id: json['id'],
          siteUrl: json['url'],
          password: json['password'],
          userName: json['username']))
      .toList();

更好的方法是将fromJsontoJson转换器作为Account类的一部分,然后您可以简单地编写:

final loadedData = receivedData
     .map((e) => Account.fromJson( e as Map<String,dynamic>))
     .toList();

相关问题