Unhandled Exception: InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>
JsonListFlutterDartJson Problem Overview
I am trying to get the JSON response from the server and output it to the console.
Future<String> login() async {
var response = await http.get(
Uri.encodeFull("https://etrans.herokuapp.com/test/2"),
headers: {"Accept": "application/json"});
this.setState(() {
data = json.decode(response.body);
});
print(data[0].name);
return "Success!";
}
> Unhandled Exception: type '_InternalLinkedHashMap
What could be the reason?
Json Solutions
Solution 1 - Json
Here are 2 common ways this could go wrong:
-
If your response is a json array like
[ { key1: value1, key2: value2, key3: value3, }, { key1: value1, key2: value2, key3: value3, }, ..... ]
Then, we use
data[0]["name"]
, notdata[0].name
Unless we cast to an object that has the name property, we cannot usedata[0].name
We cast like this
data = json.decode(response.body).cast<ObjectName>();
ObjectName
can be whatever object you want (Inbuilt or Custom). But make sure it has the name property -
If your response is a JSON object like
{ dataKey: [ { key1: value1, key2: value2, key3: value3, } ] }
Then
json.decode
will return a Map, not a ListMap<String, dynamic> map = json.decode(response.body); List<dynamic> data = map["dataKey"]; print(data[0]["name"]);
Solution 2 - Json
You can use
new Map<String, dynamic>.from(snapshot.value);
Solution 3 - Json
Easiest way (one dimensional):
Map<String, dynamic> data = new Map<String, dynamic>.from(json.decode(response.body));
print(data['name']);
Solution 4 - Json
You are trying to case an Instance of InternalLinkedHashMap
which is not possible.
You should Serialize and deserialize it back to Map<String, dynamic>
.
InternalLinkedHashMap<String, dynamic> invalidMap;
final validMap =
json.decode(json.encode(invalidMap)) as Map<String, dynamic>;
Solution 5 - Json
You have to convert the runtimeType
of data
from _InternalLinkedHashMap
to an actual List
.
One way is to use the List.from
.
final _data = List<dynamic>.from(
data.map<dynamic>(
(dynamic item) => item,
),
);
Solution 6 - Json
If you need work with generic fields has a workaround:
class DicData
{
int tot;
List<Map<String, dynamic>> fields;
DicData({
this.tot,
this.fields
});
factory DicData.fromJson(Map<String, dynamic> parsedJson) {
return DicData(
tot: parsedJson['tot'],
//The magic....
fields : parsedJson["fields"] = (parsedJson['fields'] as List)
?.map((e) => e == null ? null : Map<String, dynamic>.from(e))
?.toList()
);
}
}
Solution 7 - Json
You can get this error if you are using retrofit.dart and declare the wrong return type for your annotated methods:
@GET("/search")
Future<List<SearchResults>> getResults();
// wrong! search results contains a List but the actual type returned by that endpoint is SearchResults
vs
@GET("/search")
Future<SearchResults> getResults();
// correct for this endpoint - SearchResults is a composite with field for the list of the actual results
Solution 8 - Json
This worked for me:
- Create a List Data
- Use Map to decode the JSON file
- Use the List object Data to fetch the name of the JSON files
- With the help of index and the list object I have printed the items dynamically from the JSON file
setState(){
Map<String, dynamic> map = json.decode(response.body);
Data = map["name"];
}
// for printing
Data[index]['name1'].toString(),
Solution 9 - Json
If your working with Firebase Cloud,make sure that you're not trying to add multiple data with same DocumentID;
firestore.collection('user').document(UNIQUEID).setData(educandos[0].toJson()).
Solution 10 - Json
Seems like this error could pop up depending on various developer faults.
In my case, I was using an EasyLocalization
key but without defining it under asset/lang/en_US.json
file.
Solution 11 - Json
I had the same error using json_annotation
, json_serializable
, build_runner
. It occurs when calling the ClassName.fromJson()
method for a class that had a class property (example: class User has a property class Address).
As a solution, I modified the generated *.g.dart
files of each class, by changing Map<String, dynamic>)
to Map<dynamic, dynamic>)
in everywhere there is a deep conversion inside the method _$*FromJson
The only problem is that you have to change it again every time you regenerate your files.