Reputation: 29
In QuerySnapshot It Has "Day1" and "Day2" Boths are Day of Week Like "Saturday". If "Day1" or "Day2" is Today I need to Return "true". But This method always returns false. I need to know why the If condition (In Loop) is not working and How can I Solve this?
bool class_count(Stream<QuerySnapshot> stream) {
bool class_ = false;
String dateFormat = DateFormat('EEEE').format(DateTime.now());
//This Line Return Day Like "Saturday"
stream.forEach((element) {
if (element != null) {
for (int count = 0; count < element.documents.length; count++) {
if (element.documents[count].data['Day1'].toString() == dateFormat)
class_ = true;
if (element.documents[count].data['Day2'].toString() ==
dateFormat) if (element.documents[count].data['Day2']
.toString() ==
dateFormat) class_ = true;
}
}
});
print(class_);
return class_;
}
Upvotes: 0
Views: 265
Reputation: 2522
stream.forEach()
method returns a Future type value. So you have to call this method inside a another Asynchronous function and also it needs to be await until that future completes.
Solution:-
Convert your class_count()
synchronous method to a Asynchronous method by,
async
keyword to method header.Future<bool>
.Add await
keyword before stream.forEach()
method call (Asynchronous operation).
Code:-
[Read comments carefully to understand the program flow correctly]
//1- Return type should be a Future type => Future<bool>.
//2- Add async keyword before method body => async.
Future<bool> class_count(Stream<QuerySnapshot> stream) async{
bool class_ = false;
String dateFormat = DateFormat('EEEE').format(DateTime.now());
//3 - Adding await keyword before asynchronous operation => await.
//
await stream.forEach((element) {
if (element != null) {
for (int count = 0; count < element.documents.length; count++) {
if (element.documents[count].data['Day1'].toString() == dateFormat)
class_ = true;
if (element.documents[count].data['Day2'].toString() ==
dateFormat) if (element.documents[count].data['Day2']
.toString() ==
dateFormat) class_ = true;
}
}
});
//After stream.forEach() method completes its loop these below statements will execute.
//Every statements inside the function body will only execute one after another.
//so below statements are only executes after the above operation completes.
print(class_);
return class_;
}
One extra tip :- By using StreamSubcription you can get streams of data, instead of future.
Upvotes: 0
Reputation: 7100
Bacause stream's forEach
is asynchronous. So this loop will not wait while it completes. In your code you set class_
to false
, then create a future
which will be executed in future, and return classs_
at once. So it still equal to false
.
Try to add async
suffix to method and await
before stream.forEach
. And then your method must return Future<bool>
and been called as
final class = await class_count(someStream);
I think the best way to handle stream events is add listener for stream and process data in it.
stream.listener((event) {
// here must be your code which will be executed each time stream will get event
});
Upvotes: 3