kacpr
kacpr

Reputation: 392

JSON parses only to dynamic type, instead of Map

I was hoping someone could explain to me some bizzare behaviour whilst parsing JSON in flutter.

Here's my JSON string:

{
    "Members": {
        "Member": [
            {
                "Member_Id": "8",
            }
        ]
    }
}

There are other values in the Object(s) of the member list, I've just omitted them. For the sake of convenience I tried parsing the string the following way:

Map<String, Map<String, List<Map<String, dynamic>>>> m = json.decode(response.data);

but this causes an unhandled exception

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

When I try handling it as a simple Map with String keys and dynamic values, suddenly there are no complaints, and I can access the elements as if they were of complex type from the first example. Why does the second example works and first doesn't?

Map<String, dynamic> m = json.decode(response.data);
print(m['Members']['Member'][1]); // clearly map of map of lists, right?

Upvotes: 1

Views: 1224

Answers (2)

Robin
Robin

Reputation: 5427

Check the type of response.data

var responseDataType = response.data;
print(responseDatatype.runtimetype);

If response.data type isn't the same as parameter type m in your case, it throws an error like this

argument type of 'Map<String, Map<String, List<Map<String, dynamic>>>>' can't be assigned to the parameter type of 'String'

And when you pass value type of Map dynamic it works fine as you write

Map<String, dynamic> m = json.decode(response.data);

Here key type of Map is String and value type should be the same as response.data type, I think because of this error is happening.

Im my case when i work with json data or http request, i used to define a separate class to model(structure) my data with proper type like this

import 'dart:convert';

void main() {
  // In run time dart doesn't know what is the type of url and id. So, its better to make model for
  // handling json data defining a separate class.
  var responseData = '{"url": "https://twitter.com/", "id": 1}';

  var parsedJson = json.decode(responseData); // .decode alwasys return _JsonMap

  var jsonModel = JsonModel.fromJson(parsedJson);

  print(jsonModel.id);
  print(jsonModel.url);

}

class JsonModel {
  int id;
  String url;

  JsonModel.fromJson(parsedJson) {
    this.id = parsedJson["id"];
    this.url = parsedJson["url"];
  }
}

Upvotes: 1

diegoveloper
diegoveloper

Reputation: 103421

Try using this way:

        Map<String, dynamic> data = json.decode(response.data);
        Map<String, dynamic> members = data["members"];
        List member = members["member"];

Upvotes: 1

Related Questions