简体   繁体   中英

Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'Map<dynamic, dynamic>'

I am currently building an app to read data through an api and I am trying to parse a JSON api from JSON Placeholder and i keep getting the abpve error incase anyone has an idea i highky appreciate it.

This is the model of the app

class MachineModel {
  int id;
  String machine_name;
  String machine_number_plate;
  double location_lat;
  double location_lng;
  MachineModel({
    int id,
    String machine_name,
    String machine_number_plate,
    double location_lat,
    double location_lng,
  }) {
    this.id = id;
    this.machine_name = machine_name;
    this.machine_number_plate = machine_number_plate;
    this.location_lat = location_lat;
    this.location_lng = location_lng;
  }

  MachineModel.fromJson(Map<String, dynamic> json) {
    this.id = json['id'];
    this.machine_name = json['machine_name'];
    this.machine_number_plate = json['machine_number_plate'];
    this.location_lat = json['location_lat'];
    this.location_lng = json['location_lon'];
  }

  Map<String, dynamic> toJson() => {
        'id': this.id,
        'machine_name': this.machine_name,
        'machine_number_plate': this.machine_number_plate,
        'location_lat': this.location_lat,
        'location_lon': this.location_lng
      };
}

This is the Repo of the app

class MachineRepo {
  final DioClient dioClient;

  MachineRepo({@required this.dioClient});

  Future<ApiResponse> getMachines() async {
    try {
      Response response = await dioClient.get(
        AppConstants.GET_MACHINE_LIST_WAILON,
      );

      return ApiResponse.withSuccess(response);
    } catch (e) {
      return ApiResponse.withError(ApiErrorHandler.getMessage(e));
    }
  }

Ths is the Provider of the app

class MachineProvider with ChangeNotifier {
  final MachineRepo machineRepo;
  MachineProvider({@required this.machineRepo});
  bool _isLoading = false;
  List<MachineModel> machines = [];
  List<MachineModel> machines_ = [];
  bool get isLoading => _isLoading;
  Future getMachines() async {
    _isLoading = true;
    ApiResponse apiResponse = await machineRepo.getMachines();
    print(apiResponse);
    _isLoading = false;
    if (apiResponse.response != null &&
        apiResponse.response.statusCode == 200) {
      Map map_ = apiResponse.response.data;
      //TODO: convert API response to MachineModal List
      machines = map_['machines']
          .map<MachineModel>((machine) => MachineModel.fromJson(machine))
          .toList();
      machines_ = machines;
      print(machines);
      notifyListeners();
    } else {
      String errorMessage;
      if (apiResponse.error is String) {
        print(apiResponse.error.toString());
        errorMessage = apiResponse.error.toString();
      } else {
        ErrorResponse errorResponse = apiResponse.error;
        print(errorResponse.errors[0].message);
        errorMessage = errorResponse.errors[0].message;
      }
      notifyListeners();
    }
  }

Json

[
    {
        "id": 34406000,
        "machine_name": "Bomag race care .",
        "machine_number_plate": "",
        "location_lat": 0.922445,
        "location_lon": 34.313638
    },
    {
        "id": 244218282,
        "machine_name": "Bus test",
        "machine_number_plate": "",
        "location_lat": -0.883203,
        "location_lon": 50.66626
    },
    {
        "id": 24444459,
        "machine_name": "Test Car",
        "machine_number_plate": "",
        "location_lat": 0.2441445,
        "location_lon": 32.577147
    }
]

Any help with this

As per error said you have to convert List<dynamic> to Map<dynamic,dynamic>

You can refer the below example to Convert Map to List & List to Map

Assume that we have a model class like this.

class Customer {
  String name;
  int age;

  Customer(this.name, this.age);

  @override
  String toString() {
    return '{ ${this.name}, ${this.age} }';
  }
}

What we'll do is to convert List<Customer> into Map and vice versa as below.

 - key: Customer’s name
 - value: Customer’s age
// List of Customers
[{ Jack, 23 }, { Adam, 27 }, { Katherin, 25 }]

// Map { name:age }
{Jack: 23, Adam: 27, Katherin: 25}

Let's go to the next sections.

Convert Map to List in Dart/Flutter

Let's initialize a Dart Map first.

Map map = {'Jack': 23, 'Adam': 27, 'Katherin': 25};

We will convert this Map to List<Customer> with Customer.name from a key and Customer.age from a value.

Before that, initialize an empty list first.

var list = [];

Using Map forEach() method

Now we convert our Map to List above using forEach() method.

map.forEach((k, v) => list.add(Customer(k, v)));
print(list);

In the code above, we create a new Customer object from each key-value pair, then add the object to the list.

Output:

[{ Jack, 23 }, { Adam, 27 }, { Katherin, 25 }]

Using Iterable forEach() method

We can also convert a Dart Map to List using Iterable forEach() method instead.

map.entries.forEach((e) => list.add(Customer(e.key, e.value)));
print(list);

We apply forEach() to entries property of the map.

Every entry has a key-value field, we use them to create a new Customer object and add to the list.

Output:

[{ Jack, 23 }, { Adam, 27 }, { Katherin, 25 }]

Using Iterable map() method

Another way to convert Map to a Dart List is to use Iterable map() method.

list = map.entries.map((e) => Customer(e.key, e.value)).toList();
print(list);

Each entry item of Map's entries will be mapped to a Customer object with entry.key as customer.name and entry.value as customer.age. Then we convert the Iterable result to List using toList() method.

Output:

[{ Jack, 23 }, { Adam, 27 }, { Katherin, 25 }]

Convert List to Map in Dart/Flutter Before doing our work, we create a List with some items.

List list = [];
list.add(Customer('Jack', 23));
list.add(Customer('Adam', 27));
list.add(Customer('Katherin', 25));

Using Map.fromIterable()

We convert List<Customer> into Map using fromIterable() constructor.

var map1 = Map.fromIterable(list, key: (e) => e.name, value: (e) => e.age);
print(map1);

We pass list as an Iterable for the first param.

Then, for each element of the iterable, the method computes key and value respectively.

Output:

{Jack: 23, Adam: 27, Katherin: 25}

Using Iterable forEach() method We can convert Dart List to Map in another way: forEach() method.

var map2 = {};
list.forEach((customer) => map2[customer.name] = customer.age);
print(map2);

This method is simple to understand. We iterate over the list, for each item in the list, we add an entry (key,value) to the Map.

Output:

{Jack: 23, Adam: 27, Katherin: 25}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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