You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: rules/dart/coding-style.md
+18-8Lines changed: 18 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,18 +43,28 @@ Follow Dart conventions:
43
43
44
44
## Null Safety
45
45
46
-
- Never use `!` (bang operator) — prefer `?.`, `??`, `if (x != null)`, or Dart 3 pattern matching
47
-
- Use `?.let` style with null checks over forced unwrapping
46
+
- Avoid `!` (bang operator) — prefer `?.`, `??`, `if (x != null)`, or Dart 3 pattern matching; reserve `!` only where a null value is a programming error and crashing is the right behaviour
48
47
- Avoid `late` unless initialization is guaranteed before first use (prefer nullable or constructor init)
49
48
- Use `required` for constructor parameters that must always be provided
50
49
51
50
```dart
52
-
// BAD
51
+
// BAD — crashes at runtime if user is null
53
52
final name = user!.name;
54
53
55
-
// GOOD
54
+
// GOOD — null-aware operators
56
55
final name = user?.name ?? 'Unknown';
57
-
final name = switch (user) { User(:final name) => name, null => 'Unknown' };
56
+
57
+
// GOOD — Dart 3 pattern matching (exhaustive, compiler-checked)
58
+
final name = switch (user) {
59
+
User(:final name) => name,
60
+
null => 'Unknown',
61
+
};
62
+
63
+
// GOOD — early-return null guard
64
+
String getUserName(User? user) {
65
+
if (user == null) return 'Unknown';
66
+
return user.name; // promoted to non-null after the guard
67
+
}
58
68
```
59
69
60
70
## Sealed Types and Pattern Matching (Dart 3+)
@@ -138,9 +148,9 @@ await fetchData(); // or properly awaited
138
148
139
149
## Imports
140
150
141
-
- Use `package:` imports, not relative imports — for consistency across the codebase
final authed = context.read<AuthCubit>().state is AuthAuthenticated;
46
+
if (!authed && !state.matchedLocation.startsWith('/login')) return '/login';
47
+
return null;
48
+
},
49
+
routes: [...],
50
+
);
51
+
52
+
// Riverpod derived provider with safe firstWhereOrNull
53
+
@riverpod
54
+
double cartTotal(Ref ref) {
55
+
final cart = ref.watch(cartNotifierProvider);
56
+
final products = ref.watch(productsProvider).valueOrNull ?? [];
57
+
return cart.fold(0.0, (total, item) {
58
+
final product = products.firstWhereOrNull((p) => p.id == item.productId);
59
+
return total + (product?.price ?? 0) * item.quantity;
60
+
});
61
+
}
62
+
```
63
+
64
+
---
65
+
9
66
Practical, production-ready patterns for Dart and Flutter applications. Library-agnostic where possible, with explicit coverage of the most common ecosystem packages.
10
67
11
68
---
@@ -345,8 +402,9 @@ double cartTotal(Ref ref) {
345
402
final cart = ref.watch(cartNotifierProvider);
346
403
final products = ref.watch(productsProvider).valueOrNull ?? [];
347
404
return cart.fold(0.0, (total, item) {
348
-
final product = products.firstWhere((p) => p.id == item.productId);
349
-
return total + product.price * item.quantity;
405
+
// firstWhereOrNull (from collection package) avoids StateError when product is missing
406
+
final product = products.firstWhereOrNull((p) => p.id == item.productId);
407
+
return total + (product?.price ?? 0) * item.quantity;
350
408
});
351
409
}
352
410
```
@@ -358,6 +416,8 @@ double cartTotal(Ref ref) {
358
416
```dart
359
417
final router = GoRouter(
360
418
initialLocation: '/',
419
+
// refreshListenable re-evaluates redirect whenever auth state changes
0 commit comments