Dhevendhiran M
Dhevendhiran M

Reputation: 1263

Flutter redux store.dispatch(...) resetting the value of another redux state variable

The scenario is, when the app opens, we need to do two REST API calls,

  1. Get User Function List API call
  2. Get Chat Bubble List API call

We have two redux state variable

  1. userFunctionList
  2. chatBubbleList

state.dart

class AppState {
  final List userFunctionList;
  final List chatBubbleList;

  const AppState({
    required this.userFunctionList,
    required this.chatBubbleList,
  });

  AppState.initialState()
      : userFunctionList = [],
        chatBubbleList = [];
}

model.dart

class AddUserFunctionList {
  late final List userFunctionList;
  AddUserFunctionList({
    required this.userFunctionList,
  });
}

class AddChatBubbleList {
  late final List chatBubbleList;
  AddChatBubbleList({
    required this.chatBubbleList,
  });
}

store.dart

final store = new Store(
  appReducer,
  initialState: new AppState.initialState(),
);

reducer.dart

List userFunctionsListReducer(List existingData, dynamic action) {
  if (action is AddUserFunctionList) {
    return action.userFunctionList;
  }
  return [];
}
List chatBubbleListReducer(List existingData, dynamic action) {
  if (action is AddChatBubbleList) {
    return action.chatBubbleList;
  }
  return [];
}
AppState appReducer(AppState state, dynamic action) {
  return new AppState(
   chatBubbleList: chatBubbleListReducer(state.chatBubbleList, action),
   userFunctionList: userFunctionsListReducer(state.userFunctionList, action),
  );
}

On the homepage of the app, initState() function, we are doing two API calls,

  1. getUserFunctionList()
  2. getChatBubbleList()

In every function after receiving response, we have store.dispatch() method, like below,

At the end of function 1,

store.dispatch(AddUserFunctionList(userFunctionList: response['data']));

At the end of function 2,

store.dispatch(AddChatBubbleList(chatBubbleList: response['data]));

And the StoreConnector inside the widget builder like,

  ....
  ....
  StoreConnector<AppState, List>(
   converter: (store) => store.state.userFunctionList,
   builder: (context, userFunctionList) {
     return UserFunctionListView(
       userFunctionList: userFunctionList, 
     );
   }
   ....
   ....

If I comment out the second function and call only the first API (getUserFunctionList()), the data updates happening on the redux variable, I am able to see the UI. But If the second function also doing the store.dispatch... action, the first redux variable gets replaced with the initial value ([]).

Not able to do two store.dispatch action continuously.

Moreover, currently not using any middleware.

How to do two different store.dispatch calls while opening the app?

Upvotes: 0

Views: 595

Answers (1)

Lodewyk Roux
Lodewyk Roux

Reputation: 81

Late to answer but I believe this will help:

The issue is here I believe:

AppState appReducer(AppState state, dynamic action) {
  return new AppState(
   chatBubbleList: chatBubbleListReducer(state.chatBubbleList, action),
   userFunctionList: userFunctionsListReducer(state.userFunctionList, action),
  );
}

As you are calling the one, the other one gets called and then sets the one that finished first to [].

The easiest solution to fix this is to add a copyWith method to your AppState, and then on each of your reducer functions, just call the relevant method rather than setting the entire state from scratch (This is where you are getting the empty list once both dispatch methods has completed).

  AppState copyWith({
    final List userFunctionList,
    final List chatBubbleList,
  }) =>
      AppState(
        userFunctionList: userFunctionList?? this.userFunctionList,
        chatBubbleList: chatBubbleList?? this.chatBubbleList,
      );

You should also maybe look into combineReducers to split concerns up.

Upvotes: 1

Related Questions