Reputation: 819
After using a dataset I want to check how many datasets are unused. If I'm above the threshold I want to fetch new data.
useQuestion(Question question) async {
print("using question $question");
question.used=1;
final db = await database;
int count = await db.rawUpdate(
'UPDATE Question SET used = ? WHERE question = ?',
[question.used,question.question]);
print(question);
print("Made $count changes");
var questions = await _checkQuestionThreshold();
print(questions);
for (var q in questions) {
newQuestion(Question.fromJson(q));
}
}
Check Threshold
_checkQuestionThreshold() async {
print("count questions...");
final db = await database;
var res = await db.query("Question");
int count = Sqflite.firstIntValue(
await db.rawQuery('SELECT COUNT(*) FROM Question'));
int countUsed = Sqflite.firstIntValue(
await db.rawQuery('SELECT COUNT(*) FROM Question where used="1"'));
int i = 0;
if (count < 1 || (countUsed / count) < 0.5) {
print("Okay... we fetch new...");
return await _fetchFromFirebase();
}
Fetching from DB:
_fetchFromFirebase() async {
var questionJson;
databaseReference.once().then((DataSnapshot snapshot) async {
questionJson = await snapshot.value;
}).catchError((e) {
print(e);
});
return questionJson;
}
However I get the following error when calling for (var q in questions) {
newQuestion(Question.fromJson(q));
}
and I'm wondering what exactly I am missing.
I/flutter ( 5150): count questions...
I/flutter ( 5150): Okay... we fetch new...
I/flutter ( 5150): null
E/flutter ( 5150): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: NoSuchMethodError: The getter 'iterator' was called on null.
E/flutter ( 5150): Receiver: null
Upvotes: 0
Views: 56
Reputation: 24671
Your issue is that questions
is null, so trying to iterate over it is going to throw an error.
Looking at your code, the root of the error seems to come from your _fetchFromFirebase
method. In this case, you call databaseReference.once()
, and in the then
part you assign the result to questionJson
. However, you never await
on this call, so the _fetchFromFirebase
method ends up returning the value of questionJson
immediately after the call is made without waiting for it to finish. At that point, questionJson
will be null, so that's what gets returned.
In general, I advise to not mix the Future.then.catchError
pattern with the async/await
pattern, as it can result in confusing logic that hides what is actually happening. As such, I'd recommend sticking just to async/await
like so:
_fetchFromFirebase() async {
try {
final snapshot = await databaseReference.once();
final questionJson = await snapshot.value;
return questionJson;
} catch (e) {
print(e);
return null;
}
}
Upvotes: 1