Skip to content

Commit dbb445f

Browse files
committed
Extract all inline code from watch_ordering_rules.md (6/12)
Created watch_ordering_patterns.dart with 5 regions: - watch_inside_loops_wrong - watch_after_early_return_wrong - watch_in_callbacks_wrong - safe_pattern_conditional - safe_pattern_list_iteration All 5 inline code blocks from watch_ordering_rules.md extracted. Examples compile successfully (5 info warnings only). Progress: 6 files done, 6 remaining.
1 parent e919460 commit dbb445f

File tree

2 files changed

+127
-62
lines changed

2 files changed

+127
-62
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// ignore_for_file: unused_local_variable, unreachable_from_main, undefined_class, unused_element, dead_code
2+
import 'package:flutter/material.dart';
3+
import 'package:watch_it/watch_it.dart' hide di;
4+
5+
// Helper classes for examples
6+
class Item {
7+
final String id;
8+
final String name;
9+
Item(this.id, this.name);
10+
}
11+
12+
class Manager {
13+
final items = ValueNotifier<List<Item>>([
14+
Item('1', 'Apple'),
15+
Item('2', 'Banana'),
16+
Item('3', 'Cherry'),
17+
]);
18+
19+
final data = ValueNotifier<String>('Sample data');
20+
final isLoading = ValueNotifier<bool>(false);
21+
final error = ValueNotifier<String?>(null);
22+
}
23+
24+
// #region watch_inside_loops_wrong
25+
// ❌ WRONG - order changes based on list length
26+
class WatchInsideLoopsWrong extends WatchingWidget {
27+
@override
28+
Widget build(BuildContext context) {
29+
final items = <Item>[Item('1', 'Apple'), Item('2', 'Banana')];
30+
final widgets = <Widget>[];
31+
32+
for (final item in items) {
33+
// DON'T DO THIS - number of watch calls changes with list length
34+
final data = watchValue((Manager m) => m.data);
35+
widgets.add(Text(data));
36+
}
37+
return Column(children: widgets);
38+
}
39+
}
40+
// #endregion watch_inside_loops_wrong
41+
42+
// #region watch_after_early_return_wrong
43+
// ❌ WRONG - some watches skipped
44+
class WatchAfterEarlyReturnWrong extends WatchingWidget {
45+
@override
46+
Widget build(BuildContext context) {
47+
final isLoading = watchValue((Manager m) => m.isLoading);
48+
49+
if (isLoading) {
50+
return CircularProgressIndicator(); // Returns early!
51+
}
52+
53+
// This watch only happens sometimes - WRONG!
54+
final data = watchValue((Manager m) => m.data);
55+
return Text(data);
56+
}
57+
}
58+
// #endregion watch_after_early_return_wrong
59+
60+
// #region watch_in_callbacks_wrong
61+
// ❌ WRONG - watch in button callback
62+
class WatchInCallbacksWrong extends WatchingWidget {
63+
@override
64+
Widget build(BuildContext context) {
65+
return ElevatedButton(
66+
onPressed: () {
67+
// DON'T DO THIS - watch calls must be in build(), not callbacks
68+
final data = watchValue((Manager m) => m.data); // Error!
69+
print(data);
70+
},
71+
child: Text('Press'),
72+
);
73+
}
74+
}
75+
// #endregion watch_in_callbacks_wrong
76+
77+
// #region safe_pattern_conditional
78+
// ✓ CORRECT - All watches before conditionals
79+
class SafePatternConditional extends WatchingWidget {
80+
@override
81+
Widget build(BuildContext context) {
82+
// Watch everything first
83+
final data = watchValue((Manager m) => m.data);
84+
final isLoading = watchValue((Manager m) => m.isLoading);
85+
final error = watchValue((Manager m) => m.error);
86+
87+
// Then use conditionals
88+
if (error != null) {
89+
return ErrorWidget(error);
90+
}
91+
92+
if (isLoading) {
93+
return CircularProgressIndicator();
94+
}
95+
96+
return Text(data);
97+
}
98+
}
99+
// #endregion safe_pattern_conditional
100+
101+
// #region safe_pattern_list_iteration
102+
// ✓ CORRECT - Watch list, then iterate over values
103+
class SafePatternListIteration extends WatchingWidget {
104+
@override
105+
Widget build(BuildContext context) {
106+
// Watch the list once
107+
final items = watchValue((Manager m) => m.items);
108+
109+
// Iterate over values (not watch calls)
110+
return ListView.builder(
111+
itemCount: items.length,
112+
itemBuilder: (context, index) {
113+
final item = items[index]; // No watch here!
114+
return ListTile(title: Text(item.name));
115+
},
116+
);
117+
}
118+
}
119+
// #endregion safe_pattern_list_iteration
120+
121+
void main() {}

docs/documentation/watch_it/watch_ordering_rules.md

Lines changed: 6 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -43,37 +43,15 @@ The most common mistake is putting watch calls inside conditional statements:
4343

4444
### ❌ Watch Inside Loops
4545

46-
```dart
47-
// ❌ WRONG - order changes based on list length
48-
for (final item in items) {
49-
final data = watchValue((Manager m) => m.getItem(item.id));
50-
// Build UI...
51-
}
52-
```
46+
<<< @/../code_samples/lib/watch_it/watch_ordering_patterns.dart#watch_inside_loops_wrong
5347

5448
### ❌ Watch After Early Returns
5549

56-
```dart
57-
// ❌ WRONG - some watches skipped
58-
if (isLoading) {
59-
return CircularProgressIndicator(); // Returns early!
60-
}
61-
62-
// This watch only happens sometimes
63-
final data = watchValue((Manager m) => m.data);
64-
```
50+
<<< @/../code_samples/lib/watch_it/watch_ordering_patterns.dart#watch_after_early_return_wrong
6551

6652
### ❌ Watch in Callbacks
6753

68-
```dart
69-
// ❌ WRONG - watch in button callback
70-
ElevatedButton(
71-
onPressed: () {
72-
final data = watchValue((Manager m) => m.data); // Error!
73-
doSomething(data);
74-
},
75-
)
76-
```
54+
<<< @/../code_samples/lib/watch_it/watch_ordering_patterns.dart#watch_in_callbacks_wrong
7755

7856
## Safe Conditional Patterns
7957

@@ -88,43 +66,9 @@ ElevatedButton(
8866

8967
### Safe Pattern Examples
9068

91-
```dart
92-
// ✓ CORRECT - All watches before conditionals
93-
Widget build(BuildContext context) {
94-
// Watch everything first
95-
final data = watchValue((Manager m) => m.data);
96-
final isLoading = watchValue((Manager m) => m.isLoading);
97-
final error = watchValue((Manager m) => m.error);
98-
99-
// Then use conditionals
100-
if (error != null) {
101-
return ErrorWidget(error);
102-
}
103-
104-
if (isLoading) {
105-
return LoadingWidget();
106-
}
107-
108-
return DataWidget(data);
109-
}
110-
```
111-
112-
```dart
113-
// ✓ CORRECT - Watch list, then iterate over values
114-
Widget build(BuildContext context) {
115-
// Watch the list once
116-
final items = watchValue((Manager m) => m.items);
117-
118-
// Iterate over values (not watch calls)
119-
return ListView.builder(
120-
itemCount: items.length,
121-
itemBuilder: (context, index) {
122-
final item = items[index]; // No watch here!
123-
return ItemCard(item: item);
124-
},
125-
);
126-
}
127-
```
69+
<<< @/../code_samples/lib/watch_it/watch_ordering_patterns.dart#safe_pattern_conditional
70+
71+
<<< @/../code_samples/lib/watch_it/watch_ordering_patterns.dart#safe_pattern_list_iteration
12872

12973
## Troubleshooting
13074

0 commit comments

Comments
 (0)