0
votes

I have a problem where i want to read some data from database and i want my function to wait for the data before proceeding executing the rest of my code. i am using stream with await and async but doesnt look like it is working for me.

here is my code

void updateIncome() async {
     Stream<List<IncomeData>> _currentEntries;
     _currentEntries =  database.watchIncomeForUpdate(this.income);
    await _currentEntries.forEach((List<IncomeData> x) {
        x.forEach((element) {
          print('AWAIT');
        }
        );
      });
      print('FINISH');
  }

here is the procedure that call my database and get data

Stream<List<IncomeData>> watchIncomeForUpdate(IncomeData entry)  {
   return  (select(income)..where((t) =>t.id.isBiggerOrEqualValue(entry.id) & t.groupId.equals(entry.groupId))
     ..orderBy([(t) => OrderingTerm(expression: t.dateReceived)])).watch();
  }

when i run the function updateIncome(), it prints FINISH first which make me believe that the await/async is not working by waiting for the foreach to loop through all elements in the list.
i tried to move the await keyword in the function call

_currentEntries =  await database.watchIncomeForUpdate(this.income);

i get a warning message: await applied to Stream<List> which i not a Future can someone help me? what i am doing wrong?

i want to wait for database to get the data, loop and print AWAIT then when finish, it should proceed with rest of code and print FINISH. the function that call the database return 8 rows. so when i loop using foreach, it should print AWAIT 8 times follow by FINISH.

how can i fix my code so that the function calls the database ,loop through the elements and wait until the loop finish before proceeding with the rest of the code outside of the loop?

2
await doesn't work in forEach - Uni
Why are you using watch instead of get? - Richard Heap
hi Richard, I am using watch because I want the stream to look for changes in my database and get those changes. for example, lets say i read my database and display my data in widget. i then make a change in the database, then watch should look for any changes. if this is not how it works, can you explain the difference between both and when i can use watch and when to use get? also, do you know the solution to the problem - yoohoo

2 Answers

0
votes

Since watchIncomeForUpdate is not a Future function, you can't wait for a non-future function.

void updateIncome() async {
    await for(var x in database.watchIncomeForUpdate(this.income)){
        x.forEach((element) {
          print('AWAIT');
        }
        );
      });
      print('FINISH');
  }

Ref: https://dart.dev/tutorials/language/streams

0
votes

Thanks for all replies. i figured it out.
i changed function from this

Stream<List<IncomeData>> watchIncomeForUpdate(IncomeData entry)  {
   return  (select(income)..where((t) =>t.id.isBiggerOrEqualValue(entry.id) & t.groupId.equals(entry.groupId))
     ..orderBy([(t) => OrderingTerm(expression: t.dateReceived)])).watch();
  }

to this

 Future<List<IncomeData>>  watchIncomeForUpdate(IncomeData entry)  async {
   return  (select(income)..where((t) =>t.id.isBiggerOrEqualValue(entry.id) & t.groupId.equals(entry.groupId))
     ..orderBy([(t) => OrderingTerm(expression: t.dateReceived)])).get();
  }

then call the procedure as

      data = await database.watchIncomeForUpdate(this.income);