Home > OS >  Flutter: Type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic&
Flutter: Type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic&

Time:07-21

What I am trying is to get the data from an API to the mobile Flutter application. The API should be set up fine. The only thing where I am struggling with is this error code. I know it has something to do with a List but I didn't find the solution.

The error flutter gives:

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://---.---.-.--:7015/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()));
      }
    });
  }
}

Thanks in advance

CodePudding user response:

The API is returning an array, not a JSON object and JokeModel.fromJson(Map<String, dynamic> json) expects a Map, not a List.

I'd recommend returning from the API a proper JSON object like below. This way it's even possible to return an error status and error message.

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

You'd need also to create, for example, a JokesResponse serializable class like so:


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)),
      };
}
  • Related