Flutter: 类型“List<dynamic>”不是类型“Map<String, dynamic>”的子类型。

3

我正在尝试从API获取数据到移动Flutter应用程序。 API应该已经设置好了。 我唯一苦恼的是这个错误代码。 我知道它与List有关,但是我没有找到解决方案。

Flutter给出的错误信息:

Flutter error

API:sql api

JokeModel.dart:

JokeModel jokeModelFromJson(String str) => JokeModel.fromJson(json.decode(str));

String jokeModelToJson(JokeModel data) => json.encode(data.toJson());


class JokeModel{
final int klantId;
final String mailaddres;
final String wachtwoord;
final String klantvoornaam;
final String tussenvoegsel;
final String klantachternaam;
final String bedrijfsnaam;
final String telefoonnummer;

JokeModel({
  required this.klantId,
  required this.mailaddres,
  required this.wachtwoord,
  required this.klantvoornaam,
  required this.tussenvoegsel,
  required this.klantachternaam,
  required this.bedrijfsnaam,
  required this.telefoonnummer,
});

factory JokeModel.fromJson(Map<String, dynamic> json) {
  return JokeModel(
  klantId: json["klantId"],
  mailaddres: json["mailaddres"],
  wachtwoord: json["wachtwoord"],
  klantvoornaam: json["klantvoornaam"],
  tussenvoegsel: json["tussenvoegsel"],
  klantachternaam: json["klantachternaam"],
  bedrijfsnaam: json["bedrijfsnaam"],
  telefoonnummer: json["telefoonnummer"],
  );
}

Map<String, dynamic> toJson() => {
  "KlantId": klantId,
  "Mailaddres": mailaddres,
  "Wachtwoord": wachtwoord,
  "Klantvoornaam": klantvoornaam,
  "Tussenvoegsel": tussenvoegsel,
  "Klantachternaam": klantachternaam,
  "Bedrijfsnaam": bedrijfsnaam,
  "Telefoonnummer": telefoonnummer,
  };
}

Repository.dart:

class JokeRepository {
  final String _baseUrl = "https://---.---.-.--:port/api";

  Future <JokeModel> getJoke() async {
    final response = await http.get(Uri.parse(_baseUrl));
    if (response.statusCode == 200) {
      return jokeModelFromJson(response.body);
    } else {
      throw Exception("Failed to load joke");
    }
  }
}

Joke_bloc.dart:

class JokeBloc extends Bloc<JokeEvent, JokeState> {
  final JokeRepository _jokeRepository;

  JokeBloc(this._jokeRepository) : super(JokeLoadingState()) {
    on<LoadJokeEvent>((event, emit) async {
      emit(JokeLoadingState());
      try {
        final joke = await _jokeRepository.getJoke();
        emit(JokeLoadedState(joke));
      } catch (e) {
        emit(JokeErrorState(e.toString()));
      }
    });
  }
}

提前致谢

1个回答

1

API返回的是一个数组,而不是JSON对象。而JokeModel.fromJson(Map<String, dynamic> json)需要一个Map而不是List

我建议从API返回一个正确的JSON对象,如下所示。这样甚至可以返回错误状态和错误消息。

{
  success: true,
  result: [
    {
      klantId: 1,
      mailaddress: "XXXXXX"
      ...
    },
    {
      klantId: 2,
      mailaddress: "XXXXXX"
      ...
    },
    ...
  ]
}

你还需要创建一个可序列化类JokesResponse,示例如下:


JokesResponse jokesResponseFromJson(String str) =>
    JokesResponse.fromJson(json.decode(str));

String jokesResponseToJson(JokesResponse data) => json.encode(data.toJson());

class JokesResponse {
  final bool success;
  final List<JokeModel> result;

  JokesResponse({
    required this.success,
    required this.result,
  });

  JokesResponse.fromJson(Map<String, dynamic> json)
      : success = json["success"],
        result = (json["result"] as List)
            .map((joke) => jokeModelFromJson(joke))
            .toList();

  Map<String, dynamic> toJson() => {
        "success": success,
        "result": result.map((joke) => jokeModelToJson(joke)),
      };
}

所以如果我理解你的意思正确的话,API没有返回JSON对象。这意味着我必须更改API,以便它以与答案中提到的相同的方式显示数据库中的结果。我还需要稍微调整一下模型。 - Minimumspace
没错... 但你不必改变JokeModel。只需要为API响应创建一个名为JokesResponse的新模型来获取JokeModel列表即可。 - lepsch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接