Hi
I have an AppState and a nested MenuState.
Actions on the AppState trigger the reducer and that then triggers the UI to update.
Actions on the nested MenuState trigger the nested reducer BUT do not trigger the UI to update.
Is this a bug or am I doing something wrong?
If there is nothing obvious in my following code, would you be so kind and provide an example with a nested action and reducer that actually triggers an update using the flutter_built_redux
StoreConnection
?
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel dev, v0.5.4, on Microsoft Windows [Version 10.0.17134.112], locale en-NZ)
[√] Android toolchain - develop for Android devices (Android SDK 26.0.2)
[√] Android Studio (version 3.1)
[√] IntelliJ IDEA Community Edition (version 2017.3)
store
Store<AppState, AppStateBuilder, AppActions> createStore() {
return new Store<AppState, AppStateBuilder, AppActions>(
appReducerBuilder.build(),
new AppState.loading(),
new AppActions(),
middleware: [
createFirebaseMiddleware(),
],
);
}
middleware
final Firestore firestore = Firestore.instance;
Middleware<AppState, AppStateBuilder, AppActions> createFirebaseMiddleware() {
return (new MiddlewareBuilder<AppState, AppStateBuilder, AppActions>()
..add(AppActionsNames.connectFirestoreAction, connectFirestore))
.build();
}
connectFirestore(MiddlewareApi<AppState, AppStateBuilder, AppActions> api,
ActionHandler next, Action<Null> action) {
firestore
.collection("menus/P1N09rgDMAgc5u2KrIIT/items")
.orderBy("sortOrder")
.snapshots()
.listen((QuerySnapshot snapshot) {
BuiltList<MenuItem> menuItems =
documentsToBuiltList<MenuItem>(snapshot.documents, MenuItem.serializer);
api.actions.menu.menuItemsLoadedSuccessAction(menuItems);
});
next(action);
}
app_state
part 'app_state.g.dart';
abstract class AppState implements Built<AppState, AppStateBuilder> {
static Serializer<AppState> get serializer => _$appStateSerializer;
factory AppState([updates(AppStateBuilder b)]) = _$AppState;
AppState._();
BuiltList<Shop> get shops;
@nullable
MenuState get menuState;
menu_state
part 'menu_state.g.dart';
abstract class MenuState implements Built<MenuState, MenuStateBuilder> {
static Serializer<MenuState> get serializer => _$menuStateSerializer;
factory MenuState([updates(MenuStateBuilder b)]) = _$MenuState;
MenuState._();
@nullable
String get id;
BuiltList<MenuItem> get menuItems;
@nullable
String get title;
}
menu_item
part 'menu_item.g.dart';
abstract class MenuItem implements Built<MenuItem, MenuItemBuilder> {
static Serializer<MenuItem> get serializer => _$menuItemSerializer;
factory MenuItem([updates(MenuItemBuilder b)]) = _$MenuItem;
MenuItem._();
@nullable
String get currency;
@nullable
String get description;
String get id;
@nullable
double get price;
int get sortOrder;
String get title;
int get type;
}
app_actions
part 'app_actions.g.dart';
abstract class AppActions extends ReduxActions {
ActionDispatcher<Null> connectFirestoreAction;
ActionDispatcher<BuiltList<Shop>> shopsLoadedSuccessAction;
factory AppActions() => new _$AppActions();
AppActions._();
MenuActions get menu;
}
menu_actions
part 'menu_actions.g.dart';
abstract class MenuActions extends ReduxActions {
ActionDispatcher<BuiltList<MenuItem>> menuItemsLoadedSuccessAction;
factory MenuActions() => new _$MenuActions();
MenuActions._();
}
app_reducer
final appReducerBuilder = new ReducerBuilder<AppState, AppStateBuilder>()
..add(AppActionsNames.shopsLoadedSuccessAction, shopsLoadedSuccess)
..combineNested<MenuState, MenuStateBuilder>(menuReducerBuilder);
menu_reducer
final menuReducerBuilder =
new NestedReducerBuilder<AppState, AppStateBuilder, MenuState, MenuStateBuilder>(
(s) => s.menuState,
(b) => b.menuState) // maps from the main state object to the nested state
..add(MenuActionsNames.menuItemsLoadedSuccessAction, menuItemsLoadedSuccess);
void menuItemsLoadedSuccess(MenuState state, Action<BuiltList<MenuItem>> action,
MenuStateBuilder builder) {
builder.menuItems.replace(action.payload);
}
menu_widget
class MenuWidget extends StatefulWidget {
@override
MenuWidgetState createState() => MenuWidgetState();
}
class MenuWidgetState extends State<MenuWidget>
with SingleTickerProviderStateMixin {
// ...
@override
Widget build(BuildContext context) {
return StoreConnection<AppState, AppActions, BuiltList<MenuItem>>(
connect: (state) => state.menuState.menuItems,
builder: (BuildContext context, BuiltList<MenuItem> menuItems,
AppActions actions) {
print(menuItems); // not printed when nested action triggers nested reducer :(
return Scaffold(
// ...
floatingActionButton: FloatingActionButton(
child: Icon(Icons.control_point),
onPressed: () {
actions.connectFirestoreAction();
},
),
// ...