Convert Json of maps to list<Object> in flutter - json

I have a JSON like that
[
{
"id": "2a5",
"employeeNumber": "101",
"firstName": "Sachin",
"lastName": "Agrawal"
},
{
"id": "1f7",
"employeeNumber": "151",
"firstName": "Karsten",
"lastName": "Andersen"
},
]
I tried to parse the JSON like that
List<Employee> employees = (jsonDecode(response.data) as List)
.map((data) => Employee.fromJson(data))
.toList();
it causes the following error
List<dynamic>' is not a subtype of type 'String'
when I try to decode the JSON it causes the following error
Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'String'
what is the proper way to parse this type of JSON?

You don't need to decode your response.data, it is already in list form. So instead of this:
List<Employee> employees = (jsonDecode(response.data) as List)
.map((data) => Employee.fromJson(data))
.toList();
try this:
List<Employee> employees = (response.data as List)
.map((data) => Employee.fromJson(data))
.toList();

Related

Flutter / dart. Json.decode nested JSON

I am parsing a JSON from Firebase. When I try to decode it with jsonDecode this exception is thrown:
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type '_Map<String, dynamic>' is not a subtype of type 'Map<String, dynamic>'
To reproduce the error:
final Map<String, dynamic>> map = jsonDecode(data);
Data is the following String:
"{
"01/10/2023": {
"enter": "7:0",
"exit": "17:0",
"details": "",
"type": "0005"
},
"01/11/2023": {
"enter": "7:0",
"exit": "17:0",
"details": "",
"type": "0005"
},
"01/12/2023": {
"enter": "7:0",
"exit": "17:0",
"details": "",
"type": "0005"
}
}"
I don't understand why it returns a type that cannot be casted. I don't know the meaning of that underscore.
Try using
final Map<String, dynamic>> map = jsonDecode(data) as Map<String, dynamic>>

flutter program: _CastError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>' in type cast)

I want to display the json, but I got the error listed in the title. I have show the line that causing error. Can you help me fix it?
class _MainPage extends State<MainPage> {
List<KomikModel>? listproduk;
Future<List<KomikModel>> _fetchData() async {
final jsondata =
await rootBundle.rootBundle.loadString('assets/datakomik.json');
final list = json.decode(jsondata) as List<dynamic>; // error in this line
return list.map((e) => KomikModel.fromJson(e)).toList();
}
Here is datakomik.json, I use nested json. This is my first time using json, so I don't know how to display the nested json.
{
"data": [
{
"kategori": "New update",
"data": [
{
"judul": "Jujutsu Kaisen",
"image": "images/Jujutsu Kaisen_Volume 1.webp"
},
{
"judul": "Vinland Saga",
"image": "images/Vinland Saga_volume 01.jpg"
},
{
"judul": "Hunter x Hunter",
"image": "images/HxH_Volume 10.jpg"
},
{
"judul": "One Piece",
"image": "images/One Piece_Volume 1.webp"
}
]
},
{
"kategori": "Read",
"data": [
{
"judul": "Kaguya-sama: Love is War",
"image": "images/kaguya-sama_Volume 22.jpg"
}
]
}
]
}
You are receiving a map, and it contains data inside it, You can do
final list = jsonDecode(jsondata)["data"] as List<dynamic>;
You are parsing your JSON as List, but usualy it is Map. Try to handle it similar like this:
final jsondata =
await rootBundle.rootBundle.loadString('assets/datakomik.json');
final objects = json.decode(jsondata) as Map<String, dynamic>;
// And see that data you are recieving.
As you can see in you json file, it contains Map not a list so try this:
final _data = json.decode(jsondata)["data"] as List<dynamic>;

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

I send a request to server and when the status code is 200 everything is ok i can decode the returned json, but when the status isn't 200 i have a problem
here's the json of status code 200:
{
"success": true,
"statusCode": 200,
"code": "jwt_auth_valid_credential",
"message": "Credential is valid",
"data": {
"token": "a token",
"id": 42626,
"email": "example#gmail.com",
"nicename": "",
"firstName": "",
"lastName": "",
"displayName": ""
}
}
i have adjusted the type of data as a nested structure and it's fine,
the json of else status codes is like this:
{
"success": false,
"statusCode": 403,
"code": "invalid_username",
"message": "Error: The username ** is not registered on this site. If you are unsure of your username, try your email address instead.",
"data": []
}
and here's my problem the returned data value is an empty array and idk how to handle it.
here's my model class:
class loginpagemodel{
late final message;
late final Data data;
loginpagemodel({
this.message,required this.data });
factory loginpagemodel.fromJson(Map<String , dynamic> parsedJson){
return loginpagemodel(
message: parsedJson['message'],
data: Data.fromJson(parsedJson['data']
),
);
}
}
class Data{
late final id;
late final displayName;
Data({this.id,this.displayName});
factory Data.fromJson(Map<String,dynamic> parsedJson){
return Data(
id: parsedJson['id'],
displayName: parsedJson['displayName'],
);
}
}
Thanks for ur answers in advance.
The problem is when the status code isnt 200 the data field is List. A possible solution:
factory loginpagemodel.fromJson(Map<String , dynamic> parsedJson){
return loginpagemodel(
message: parsedJson['message'],
data: Data.fromJson(
parsedJson['data'] == []? // if data is [] (the status code isnt 200)
{} : // empty map
parsedJson['data'] // the data field
),
);
}
You can basically control your data, if it is not empty, you can use.
Just one example;
if(myJson["data"].length == 0 ) {
print("there is no data");
}else{
print("there is data: ${myJson["data"].toString()}");
}
You could make data field nullable: Data? data.
You will need just to check it with "isEmpty" or "isNotEmpty" later.

Cannot group JSON array because of typecasting error

I have an API that returns an array of dictionaries and I'm trying to group it by the date key in each item using Swift's Dictionay(grouping:) function.
The JSON looks like this:
[
{ "date": "2018-12-12", "name": "abc" },
{ "date": "2018-12-12", "name": "def" },
{ "date": "2018-12-13", "name": "def" },
...
]
I have the following swift code that generates a compilation error:
let json = response.result.value as! Array<[String:AnyObject]>
let groupedByDate = Dictionary(grouping: json, by: { (item) -> String in
return (item as! [String:AnyObject])["date"]
})
When I compile I get this error:
Cannot subscript a value of type '[String : AnyObject]' with an index of type 'String'
and this warning:
Cast from '_' to unrelated type '[String : AnyObject]' always fails
I'm very confused because the item variable is clearly of type [String:AnyObject] and I am able to index into the json in the debugger by doing po json[0]["date"].
Your code contradicts itself. When you say
let groupedByDate = Dictionary(grouping: json, by: {
(item) -> String in
you are making a contract that you will return a String from this closure.
But when you then say
return (item as! [String:AnyObject])["date"]
you are returning an AnyObject, not a String.

How to (de-)serialize a list of objects?

I found an example of JSON serialization and deserialization to objects in Flutter
but how to do that with a list of persons like:
[
{
"name": "John",
"age": 30,
"cars": [
{
"name": "BMW",
"models": [
"320",
"X3",
"X5"
]
}
]
},
{
"name": "John",
"age": 30,
"cars": [
{
"name": "Ford",
"models": [
"Fiesta",
"Focus",
"Mustang"
]
}
]
}
]
When I call _person = serializers.deserializeWith(Person.serializer, JSON.decode(json)); I get this error:
The following _CastError was thrown attaching to the render tree:
type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String' in type cast where
_InternalLinkedHashMap is from dart:collection
String is from dart:core
String is from dart:core
I created a surrounding Persons class:
abstract class Persons implements Built<Persons, PersonsBuilder> {
BuiltList<Person> get persons;
Persons._();
factory Persons([updates(PersonsBuilder b)]) = _$Persons;
static Serializer<Persons> get serializer => _$personsSerializer;
}
and call _person = serializers.deserializeWith(Persons.serializer, JSON.decode(json)); but the error is the same.
How to (de-)serialize a Json list of objects?
Instead of
_person = serializers.deserializeWith(Person.serializer, JSON.decode(json));
Try
_person = serializers.deserializeWith(Person.serializer, (JSON.decode(json) as List).first);
Or
var personList = (JSON.decode(json) as List).map((j) => serializers.deserializeWith(Person.serializer, j)).toList();