the following situation: I want to make a ToDo list with a Cubit. That the ToDo list does not disappear after leaving the app, I found the package hydrated Bloc. When I created the HydratedCubit with the 2 override methods for the FromJson and ToJson, creating them Inside the ToDoState and executed it, I got an exception, "Converting object to an encodable object failed: Instance of ‘Todo’". After research I found out that JSON can’t convert such a model and you have to overwrite these models with working From and To functions first. I tried this with the package "json serializable". Here I had to ask myself in which class I have to add the "@JsonSerializable()", inside the Todo model or the todo state, in which the error appears? I decided to add the @ for my todostate because adding it on the Todo model didn’t change anything. After this package created me the "todo_list_state.g.dart" I don’t get the error anymore, BUT: It also doesn’t save the list, looks like HydratedCubit is being "ignored". Here a few code snippets:
First, I show you the Todo Model:
Uuid uuid = const Uuid();
class Todo extends Equatable {
final String id;
final String desc;
final double menge;
Todo( {
String? id,
required this.desc,
required this.menge,
}) : id = id ?? uuid.v4();
}
I left out the to string and props…
As I mentioned before, I tried to add the JsonSerializableGenerator inside this class, but this didn’t change something.
Here is my TodoListState:
part of 'todo_list_cubit.dart';
@JsonSerializable()
class TodoListState extends Equatable {
final List<Todo> todos;
factory TodoListState.initial() {
return TodoListState(todos: []);
}
Map<String, dynamic>toMap() => _$FoodListStateToMap(this, food);
factory FoodListState.fromMap(Map<String, dynamic> map) => _$FoodListStateFromMap(map);
}
Here are the generated functions inside ‘todo_list_state.g.dart’:
TodoListState _$TodoListStateFromMap(Map<String, dynamic> map) {
return TodoListState (
todo: map['todo'] as List<TodoModel>,
);
}
Map<String, dynamic> _$TodoListStateToMap(TodoListState instance, List<TodoModel> todo) {
return {
'todo': todo,
};
}
At last here my Cubit functions where I override the From and To:
@override
TodoListState? fromJson(Map<String, dynamic> json) {
return TodoListState.fromMap(json);
}
@override
Map<String, dynamic>? toJson(TodoListStatestate) {
return state.toMap();
}
So does anybody know why my Hydrated Cubit doesn’t save my list? Or do I have to convert the Model but just dont know how?… Appreciate your help. Thanks
2
Answers
Both model and states need to have
toJson
andfromJson
methods. So the approach was right with usingJsonSerializable
. But converting objects to and from json is a very important thing to understand how to do without codegen tools. Those can be boilerplate and not always converting correctly complex objects. When doing it manually, it’s also easier to debug. So in your case, additions to the model would be:Then, in your states (again, I am not going to use
JsonSerializable
):Then in your Cubit nothing changes
Except for you may want to add all sorts of null safety checks around the conversions, because I omitted all aspects not related to the topic of the question.
Persisting single instance of todo
TodoCubit.dart
ToDoState.dart
Home.dart
main.dart
Output:
To store multiple instance of todo that is list of todos refer this example
@Credit for the example : @Olga P