Reputation: 819
Hi everyone this is my whole method :
Future<void> init() async {
FirebaseAuth.instance.userChanges().listen((user) {
if (user != null) {
_loginState = ApplicationLoginState.loggedIn;
_guestBookSubscription = FirebaseFirestore.instance
.collection('guestbook')
.orderBy('timestamp', descending: true)
.limit(3)
.snapshots()
.listen((snapshot) {
_guestBookMessages = [];
snapshot.docs.forEach((document) {
_guestBookMessages.add(
GuestBookMessage(
name: document.data()['name'] as String,
message: document.data()['text'] as String,
),
);
});
notifyListeners();
});
} else {
_loginState = ApplicationLoginState.loggedOut;
_guestBookMessages = [];
_guestBookSubscription?.cancel();
}
notifyListeners();
});
}
the part that dart complains about is this one :
snapshot.docs.forEach((document) {
_guestBookMessages.add(
GuestBookMessage(
name: document.data()['name'] as String,
message: document.data()['text'] as String,
),
);
});
how can I change this method without ruining the whole functionality ? Im just looking for a way that makes dart happy . I appreciate your help in advance.
Upvotes: 42
Views: 21586
Reputation: 234
There is a debate below the accepted answer, about readability of the recommended lint rules at stake here. This is the rule in question causing the problem : https://dart.dev/tools/linter-rules/avoid_function_literals_in_foreach_calls
You can disable it by modifying your analysis_options.yaml file :
linter:
rules:
avoid_function_literals_in_foreach_calls: false
Upvotes: 3
Reputation: 1186
AVOID using forEach with a function literal.
AVOID:
snapshot.docs.forEach((document) {
...
});
GOOD:
for (var document in snapshot.docs) {
// Rest of your code
}
Upvotes: 54
Reputation: 885
Using like data.forEach(function);
example:
void main() async {
List<int> list = [1, 2, 3, 4, 5];
//recommended
list.forEach(showSquareNumbers);
//not recommended
list.forEach((int number) => showSquareNumbers(number));
list.forEach((int number) {
showSquareNumbers(number);
});
}
void showSquareNumbers(int data) {
print("$data * $data = ${data * data}");
}
This is my opinion.
I think the forEach
seems more complicated than the for
loop and the forEach
can't use continue
and break
(return
is available but not a thing happens when using return
).
void test(List data) {
data.forEach((element) {
print(element);
if(element) return;
});
for (var element in data) {
print(element);
if(element) continue;
if(element) break;
if(element) return;
}
}
I think we should use the for
instead of the forEach
loop when your forEach
loop seems like this code below because the for
loop have many options more than forEach
as I said.
data.forEach((element) {
print(element)
});
//or
data.forEach((element) => print(element));
I think the forEach
loop is used for short code (easy to understand) and when you want to do something you don't care about the result like this code (using with Function(dynamic)
).
void test(List data) {
void showInTerminal(e) {
print("data is $e");
}
data.forEach(showInTerminal);
Function(dynamic) function = showInTerminal;
data.forEach(function);
}
Make sure the data type and function(type) are the same.
//error
void test(List<Map> data) {
void showInTerminal(String e) {
print("data is $e");
}
data.forEach(showInTerminal);
}
//success
void test(List<Map> data) {
void showInTerminal(Map e) {
print("data is $e");
}
data.forEach(showInTerminal);
}
I code like this. I think it's easy to read.
void test() {
dataList.forEach(removeData);
fileList.forEach(removeFile);
}
Upvotes: 6
Reputation: 28876
Use await for
:
await for (final document in snapshot.docs) {
// Your code...
}
Upvotes: -5