0x45
0x45

Reputation: 819

Flutter async programming

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

Answers (1)

Abion47
Abion47

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

Related Questions