I'm trying to make a method to add entries in a Hive box but after adding my id key is always null. now I know I can change the key at onPressed() by:
getIt<TodoDatasource>().addTodo(Todo(
id: 0, // <----------------------------- IN QUESTION
name: _controlName.text,
description: _controlDescription.text,
completed: 0, // default
));
but doing this will affect the id on my other data sources, SQFLite(which can assign an auto-increment at the id column), and Firebase RTDB(which generates an id for each entry).
what I noticed as well is Hive is also generating an auto-increment on each entry AND based on this GitHub post "click me!", the .add() method returns an int. that's not the case as on my project this returns a Future so can't seem to use that to match my id. is there a solution or a workaround for this problem?
here's the necessary code blocks:
DataServiceManager class
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:todo_list1/local_hive_datasource.dart';
import 'package:todo_list1/local_sqlite_datasource.dart';
import 'package:todo_list1/services/todo_datasource.dart';
import 'package:todo_list1/remote_api_datasource.dart';
import 'dart:io' show Platform;
import '../models/todo.dart';
class DataServiceManager implements TodoDatasource {
late final TodoDatasource _local;
final TodoDatasource _remote = RemoteApiDatasource();
DataServiceManager() {
// if (kIsWeb) {
// _local = LocalHiveDatasource();
// } else {
// _local = LocalSQLiteDatasource();
// }
_local = LocalHiveDatasource();
}
Future<bool> _checkConnectivity() async {
if (!Platform.isAndroid ||
!Platform.isWindows ||
!Platform.isFuchsia ||
!Platform.isIOS ||
!Platform.isLinux ||
!Platform.isMacOS) {
if (kIsWeb &&
await Connectivity().checkConnectivity() == ConnectivityResult.none) {
return false;
}
}
return true;
}
@override
Future<bool> addTodo(Todo t) async {
// return await _checkConnectivity()
// ? await _remote.addTodo(t)
// : await _local.addTodo(t);
return _local.addTodo(t);
}
@override
Future<bool> updateTodo(Todo t) async {
// return await _checkConnectivity()
// ? await _remote.updateTodo(t)
// : await _local.updateTodo(t);
return _local.updateTodo(t);
}
@override
Future<bool> deleteTodo(Todo t) async {
// return await _checkConnectivity()
// ? await _remote.deleteTodo(t)
// : await _local.deleteTodo(t);
return _local.deleteTodo(t);
}
@override
Future<List<Todo>> getAllTodo() async {
// return await _checkConnectivity()
// ? await _remote.getAllTodo()
// : await _local.getAllTodo();
return _local.getAllTodo();
}
@override
Future<List<Map<String, Object?>>> getId(int i) {
// return await _checkConnectivity()
// ? await _remote.getAllTodo()
// : await _local.getAllTodo();
return _local.getId(i);
}
}
LocalHiveDatasource class
import 'package:hive_flutter/hive_flutter.dart';
import 'package:todo_list1/models/todo.dart';
import 'package:todo_list1/services/todo_datasource.dart';
class LocalHiveDatasource implements TodoDatasource {
bool initialised = false;
int _id = 0; // <----------------------------my workaround
LocalHiveDatasource() {
init();
}
Future<void> init() async {
await Hive.initFlutter();
Hive.registerAdapter(TodoAdapter());
await Hive.openBox('todos_box');
initialised = true;
}
@override
Future<bool> addTodo(Todo t) async {
// MY WORKAROUND
// can add before pushing to the box but when the app exits,
// the _id rolls back to 0
// therefore the instance of entry will not match the id...
if (t.id == null) {
_id++;
t.id = _id;
}
// conversion of todos model to map
final Map<String, dynamic> todoToMap = t.toMap();
final box = await Hive.openBox('todos_box');
box.add(todoToMap);
await box.close();
return true;
}
@override
Future<bool> deleteTodo(Todo t) async {
throw UnimplementedError();
}
@override
Future<List<Todo>> getAllTodo() async {
if (!initialised) return <Todo>[];
// opens the box
Box box = await Hive.openBox('todos_box');
Map<dynamic, dynamic> retrievedMapdData = box.toMap();
box.close();
return List.generate(retrievedMapdData.length, (index) {
return Todo(
id: retrievedMapdData[index]['id'],
name: retrievedMapdData[index]['name'],
description: retrievedMapdData[index]['description'],
completed: retrievedMapdData[index]['completed'],
);
});
}
@override
Future<List<Map<String, Object?>>> getId(int i) async {
throw UnimplementedError();
}
@override
Future<bool> updateTodo(Todo t) async {
throw UnimplementedError();
}
}