clean architecture toJson with sublist (reso coder)
Solution 1
I now solved it in the following way.
I´ve added a method to the model class to cast the entity to the model
factory ItemModel.fromItem(Item item) {
if (item is ItemModel) {
return item;
}
return ItemModel(
text: item.text,
);
}
And adapted the toJson method
...toJson(){
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.items != null) {
data['items'] = this.items.map((v) => ItemModel.fromItem(v).toJson()).toList();
}
return data;
}
Solution 2
You are using Item.fromJson
instead of ItemModel.fromJson
? Have you tried this ?
class OrderModel extends Item {
...
...fromJson() {
if (json['items'] != null) {
teams = new List<ItemModel>();
json['items'].forEach((v) {
items.add(ItemModel.fromJson(v));
});
}
}
}
Edit
If you to call toJson on Item directly, you can cast it's value to ItemModel as following
...toJson(){
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.items != null) {
data['items'] = this.items.map((v) => (v as ItemModel).toJson()).toList();
}
return data;
}
Edit 2
Make your Item class abstract and add abstract methods fromJson a and toJson
abstract class Item {
//...
Item fromJson(Map json); // abstract method
Map<String, dynamic> toJson(); // abstract method
}
Comments
-
A.K. over 1 year
I am trying to use clean architecture (explained by reso coder: https://resocoder.com/2019/09/09/flutter-tdd-clean-architecture-course-4-data-layer-overview-models/) in my project.
In his example he implements an entity and a model extending the entity. The entity has all of the properties and the model implements the fromJson and toJson Methods.
It works well with "flat" classes.
But now I want to implements that for a class that has a list of another class.
class Item { String text; } class ItemModel extends Item{ ...toJson ...romJson } class Order { ... List<Item> items; } class OrderModel extends Item { ... ...fromJson() { if (json['items'] != null) { teams = new List<ItemModel>(); json['items'].forEach((v) { items.add(Item.fromJson(v)); }); } } } ...toJson(){ final Map<String, dynamic> data = new Map<String, dynamic>(); if (this.items!= null) { data['items'] = this.items.map((v) => v.toJson()).toList(); } return data; }
Of course it doenn´t work, because the class item does not have a method "toJson".
What is the correct way to implement it? Cast the List to List in the toJson method?
EDIT
When I try to cast the list items to ItemModel and there is an Item in the list, then an exception is thrown:
type 'Item' is not a subtype of type 'ItemModel' in type cast
I would now consider the following to be correct: Add a factory method to the ItemModel that cast an Item to an ItemModel:
fromItem(Item item){ if(item is ItemModel) { return item as ItemModel; } return ItemModel(..: item...); }
Is that the best way to solve this?
-
A.K. over 3 yearsWow, this Day was to long.
-
A.K. over 3 yearssorry i have posted the wrong method. The fromJson method ist ok. but i have the problem with toJson
-
A.K. over 3 yearsok, but is it ok to cast it without any checks? It could be possible that there is an Item in that list without the toJson method.
-
dm_tr over 3 yearsBoss,
ItemModel
directly extendsItem
. I can't any problem castingItem
toItemModel
-
dm_tr over 3 yearsAnother way is my using
abstract method
in yourItem
class. So that any class extending it must implement..fromJson
and..toJson
-
A.K. over 3 yearshi, i changed my question, because your solution throws an exception.
-
dm_tr over 3 yearsThis is only possible when you create abstract methods in your class
Item
-
A.K. over 3 yearsHmm, i dont like your solution. I think it´s not the way clean architecture handles Entities and Models.
-
dm_tr over 3 yearsSo unless you change items type in
OrderModel
toList<ItemModel> items;
, otherwise what you are trying to do is not possible -
A.K. over 3 yearsI try to understand how this has to be handled in reso coders clean architecture. The Datasources returning the model classses and the repositories the entities. The entities are not abstract and the the entities extending the models. The entities dont have toJson or FromJson methods..Thats the starting situation. From this situation I try to understand how to implement a entitiy with a child list the right way.
-
w461 almost 3 yearsHi, is your solution still your preferred way or did you meanwhile came up with something more "elegant"? I just created a similar question here: stackoverflow.com/questions/68624601/…
-
A.K. almost 3 yearsHi, yes, it´s still my preferred way.
-
miloskarakas about 2 years@A.K. Same here, I had no other way of doing it. It makes sense since the model should be responsible for all data conversions. Thanks for putting your answer here, you confirmed my approach.
-
miloskarakas about 2 yearsI just named it fromBase to make it uniform across all models