The following is the outline of a function in a Flutter application which retrieves from a database and maps the result set to objects:
class SQLHelper {
static Future<List<MyObject>> retrieve(int moduleId) async {
final db = await openDatabaseFromAssets('myTable.db');
final List<Map<String, dynamic>> maps = await db
.rawQuery('SELECT * FROM mytable WHERE moduleid = ?', [moduleId]);
return List.generate(maps.length, (i) {
return const MyObject(
// pass result set to MyObject constructor
);
});
}
}
Future<Database> openDatabaseFromAssets(String dbName) async {
// Get the temporary directory (cache)
final directory = await getTemporaryDirectory();
final path = join(directory.path, dbName);
// Check if the database file exists
final exists = await File(path).exists();
if (!exists) {
// Copy from assets
ByteData data = await rootBundle.load('assets/db/$dbName');
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
// Write and flush the bytes written
await File(path).writeAsBytes(bytes, flush: true);
}
// Open the database
return await openDatabase(path);
}
When debugging, the openDatabaseFromAssets
method is called as expected, but after the following line:
directory = await getTemporaryDirectory();
the debugger stops after the line which calls the retrieve
method. As no data is yet retrieved, there is a null error. Then, the application continues in the openDatabaseFromAssets
function, on the line after the call to getTemporaryDirectory
.
The retrieve
method is called as follows:
List<Sentence> getMyObjects(int moduleId) {
List<MyObject>? sss;
Future<List<MyObject>> s = SQLHelper.retrieve(moduleId);
s.then((value) => sss = value);
return sss!;
}
getTemporaryDirectory
is defined in path_provider.dart
.
In pubspec.yaml, db path is declared as follows:
assets:
- assets/db/
What could account for this?
Thanks
2
Answers
The problem might be with the use of
const
in theList.generate
method, as you cannot use const with asynchronous operations.Here’s the corrected code:
I think there is an issue in the query retrieving list type in the
retrieve
function. Try with dynamic map list type, like below: