Skip to content

Commit c271f97

Browse files
committed
selector example
1 parent 4e5c6fa commit c271f97

File tree

1 file changed

+198
-0
lines changed

1 file changed

+198
-0
lines changed

example/selector.dart

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
import 'package:built_collection/built_collection.dart';
2+
import 'package:distinct_value_connectable_stream/distinct_value_connectable_stream.dart';
3+
import 'package:rx_redux/rx_redux.dart';
4+
5+
//
6+
// [BEGIN] STATE
7+
//
8+
9+
class Book {
10+
final String id;
11+
final String userId;
12+
final String name;
13+
14+
Book(this.id, this.userId, this.name);
15+
16+
@override
17+
bool operator ==(Object other) =>
18+
identical(this, other) ||
19+
other is Book &&
20+
runtimeType == other.runtimeType &&
21+
id == other.id &&
22+
userId == other.userId &&
23+
name == other.name;
24+
25+
@override
26+
int get hashCode => id.hashCode ^ userId.hashCode ^ name.hashCode;
27+
28+
@override
29+
String toString() => 'Book{id: $id, userId: $userId, name: $name}';
30+
}
31+
32+
class User {
33+
final String id;
34+
final String name;
35+
36+
User(this.id, this.name);
37+
38+
@override
39+
bool operator ==(Object other) =>
40+
identical(this, other) ||
41+
other is User &&
42+
runtimeType == other.runtimeType &&
43+
id == other.id &&
44+
name == other.name;
45+
46+
@override
47+
int get hashCode => id.hashCode ^ name.hashCode;
48+
49+
@override
50+
String toString() => 'User{id: $id, name: $name}';
51+
}
52+
53+
class State {
54+
final User? selectedUser;
55+
final BuiltList<Book> allBooks;
56+
final Object? error;
57+
58+
State(this.selectedUser, this.allBooks, this.error);
59+
60+
@override
61+
bool operator ==(Object other) =>
62+
identical(this, other) ||
63+
other is State &&
64+
runtimeType == other.runtimeType &&
65+
selectedUser == other.selectedUser &&
66+
allBooks == other.allBooks &&
67+
error == other.error;
68+
69+
@override
70+
int get hashCode =>
71+
selectedUser.hashCode ^ allBooks.hashCode ^ error.hashCode;
72+
73+
@override
74+
String toString() =>
75+
'State{selectedUser: $selectedUser, allBooks: $allBooks, error: $error}';
76+
}
77+
78+
//
79+
// [END] STATE
80+
//
81+
82+
//
83+
// [BEGIN] ACTION
84+
//
85+
86+
abstract class Action {}
87+
88+
class ChangeSelectedUserAction implements Action {
89+
final User? user;
90+
91+
ChangeSelectedUserAction(this.user);
92+
}
93+
94+
class AddBookAction implements Action {
95+
final Book book;
96+
97+
AddBookAction(this.book);
98+
}
99+
100+
class ErrorAction implements Action {
101+
final Object error;
102+
103+
ErrorAction(this.error);
104+
}
105+
106+
//
107+
// [END] ACTION
108+
//
109+
110+
//
111+
// [BEGIN] DEMO
112+
//
113+
114+
State reducer(State state, Action action) {
115+
if (action is ChangeSelectedUserAction) {
116+
return State(
117+
action.user,
118+
state.allBooks,
119+
state.error,
120+
);
121+
}
122+
if (action is AddBookAction) {
123+
return State(
124+
state.selectedUser,
125+
state.allBooks.rebuild((b) => b.add(action.book)),
126+
state.error,
127+
);
128+
}
129+
if (action is ErrorAction) {
130+
return State(
131+
state.selectedUser,
132+
state.allBooks,
133+
action.error,
134+
);
135+
}
136+
137+
return state;
138+
}
139+
140+
void main() async {
141+
final store = RxReduxStore<Action, State>(
142+
initialState: State(null, <Book>[].build(), null),
143+
sideEffects: [],
144+
reducer: reducer);
145+
146+
// select 2 pieces of state and combine them.
147+
final visibleBooks$ = store.select2(
148+
(s) => s.selectedUser?.id,
149+
(s) => s.allBooks,
150+
(String? userId, BuiltList<Book> books) {
151+
print(
152+
'<> Call projector with userId=${userId} and books=${books.length}');
153+
154+
return userId != null && books.isNotEmpty
155+
? books.where((b) => b.userId == userId).toBuiltList()
156+
: books;
157+
},
158+
);
159+
160+
// logging state.
161+
print('~> ${visibleBooks$.value}');
162+
visibleBooks$.listen((s) => print('~> $s'));
163+
164+
// dispatch actions.
165+
[
166+
ChangeSelectedUserAction(User('0', 'Petrus')),
167+
AddBookAction(Book('0', '0', 'Book 0')),
168+
AddBookAction(Book('1', '0', 'Book 1')),
169+
AddBookAction(Book('2', '0', 'Book 2')),
170+
AddBookAction(Book('3', '0', 'Book 3')),
171+
].forEach(store.dispatch);
172+
await Future<void>.delayed(const Duration(seconds: 1));
173+
print('---------------------------------------------------');
174+
175+
[
176+
ErrorAction('Error 1') /* has no effect */,
177+
ChangeSelectedUserAction(
178+
User('0', 'Hoc')) /* same user id -> has no effect */,
179+
ChangeSelectedUserAction(
180+
User('0', 'Nguyen')) /* same user id -> has no effect */,
181+
ChangeSelectedUserAction(User('1', 'Hello')),
182+
ErrorAction('Error 2') /* has no effect */,
183+
AddBookAction(Book('4', '1', 'Book 4')),
184+
ChangeSelectedUserAction(User('0', 'Rx redux 1')),
185+
ChangeSelectedUserAction(
186+
User('0', 'Rx redux 2')) /* same user id -> has no effect */,
187+
ErrorAction('Error 3') /* has no effect */,
188+
].forEach(store.dispatch);
189+
await Future<void>.delayed(const Duration(seconds: 1));
190+
print('---------------------------------------------------');
191+
192+
// end by disposing store.
193+
await store.dispose();
194+
}
195+
196+
//
197+
// [END] DEMO
198+
//

0 commit comments

Comments
 (0)