Reputation: 132
Hello i have the following code
class TodoProvider {
Database db;
TodoProvider() {
_initDatabase();
print("Db is >>>>> $db");
}
void _initDatabase() async {
final database = await AppDatabase().connect();
db = database;
}
Future<Todo> insertTodo(Todo todo) async {
todo.id = await db.insert('todo', todo.toMap());
return todo;
}
Future<Todo> getTodo(int id) async {
List<Map<String, dynamic>> maps =
await db.query('todo', where: 'id=?', whereArgs: [id]);
if (maps.length > 0) {
return Todo.fromMap(maps.first);
}
return null;
}
Future<int> deleteTodo(int id) async {
return await db.delete('todo', where: 'id=?', whereArgs: [id]);
}
Future<int> updateTodo(Todo todo) async {
return await db
.update('todo', todo.toMap(), where: 'id=?', whereArgs: [todo.id]);
}
Future close() async => db.close();
}
The AppDatabase is a class that exposes the connect() method which returns a future.
The Goal is to assign the value returned from AppDatabase into the db class variable
Most methods in the TodoProvider class relays on the db class variable to work with the database.
The problem is that class variable db is always null
Upvotes: 0
Views: 50
Reputation: 31309
You code right now depends on the db
variable is being set which happens inside an async operation. There are two ways to fix this:
You can create a private constructor which can be called by a static method which are allowed to return Future<TodoProvider>
which the user can await on.
class TodoProvider {
...
TodoProvider._(this.db) {
print("Db is >>>>> $db");
}
static Future<TodoProvider> getInstance() async {
return TodoProvider._(await AppDatabase().connect());
}
...
}
This is not the prettiest solution but still a way to do it. Since you are allowed to await
on the same Future
multiple times, you can just await
every time you need to access the Database
object.
class TodoProvider {
Future<Database> _db;
TodoProvider() {
_initDatabase();
print("Db is >>>>> $db");
}
void _initDatabase() {
_db = AppDatabase().connect();
}
Future<Todo> insertTodo(Todo todo) async {
final db = await _db;
todo.id = await db.insert('todo', todo.toMap());
return todo;
}
Future<Todo> getTodo(int id) async {
final db = await _db;
List<Map<String, dynamic>> maps =
await db.query('todo', where: 'id=?', whereArgs: [id]);
if (maps.length > 0) {
return Todo.fromMap(maps.first);
}
return null;
}
Future<int> deleteTodo(int id) async {
final db = await _db;
return await db.delete('todo', where: 'id=?', whereArgs: [id]);
}
Future<int> updateTodo(Todo todo) async {
final db = await _db;
return await db
.update('todo', todo.toMap(), where: 'id=?', whereArgs: [todo.id]);
}
Future close() async {
final db = await _db;
db.close();
}
}
Upvotes: 1