2

I am trying to use redux_thunk but what I really don't understand from the demo is how to send parameters to that function. I have a file actions.dart where are have all the actions. From my component I want to dispatch to that action some parameters so that I make a request to API. For example I want to login with username, password without saving them in state

   actions.dart    
final ThunkAction<AppState> login = (Store<AppState> store) async {
          await new Future.delayed(
            new Duration(seconds: 3),
                () => "Waiting complete",
          );
          store.dispatch(OtherAction(....));
        };

    component.dart
class LoginBtn extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return StoreConnector<AppState, Function>(
                converter: (store) => (){
                  login(store);
                },
                builder: (context, callback) {
                  return RaisedButton(
                      highlightElevation: 20.0,
                      child: Text('Login', style: TextStyle(color: Colors.white)),
                      color: Color(0xFF0f7186),
                      onPressed: () {
                        callback();
                      });
                });
          }
        }

Can someone help me with some quick fix or demo. Thanks!

Something like this?

class MyAction {
  String gender;

  MyAction(
      {this.gender});

  ThunkAction<AppState> getDate() {
    return (Store<AppState> store) async {...};
  }
}
cosinus
  • 1,905
  • 3
  • 15
  • 21

3 Answers3

7

I think the easiest way to do it is using a function for creating the action:

ThunkAction<String> waitAndDispatch(int secondsToWait) {
   return (Store<String> store) async {
     final searchResults = await new Future.delayed(
       new Duration(seconds: secondsToWait),
       () => "Search Results",
     );

     store.dispatch(searchResults);
   };
 }

then, dispatch it like:

store.dispatch(waitAndDispatch(3));
yoavr
  • 151
  • 2
  • 5
2

There are two ways to go about doing this. Two of them wrap the action you're about to dispatch in a class like what you did above.

class MyAction {
  String gender;
  String name;
  MyAction(this.gender, this.name);

  void getDate<AppState>(Store<AppState> store) {
    print("store is $store, gender is $gender, name is $name");
  }
}

1. Create another middleware or modify the current one. Call the getDate() from within the middleware. Eg.

// this middleware intercepts any MyAction
void myMiddleware<AppState>(
  Store<AppState> store,
  dynamic action,
  NextDispatcher next
) {
  if (action is MyAction) {
    action.getDate(store);
  } else {
    next(action);
  }
}

Then we dispatch as such:

store.dispatch(new MyAction("m", "Peterson")) ;

2. Instead of modifying or creating another middleware, we make getDate() a ThunkAction and call the getDate() before dispatching. Eg.

class MyAction {
  String gender;
  String name;
  MyAction(this.gender, this.name);

  ThunkAction<AppState> getDate = (Store<AppState> store) {
    print("store is $store, gender is $gender, name is $name");
  }
}

Then we dispatch it like so:

store.dispatch(new MyAction(...).getDate)

The second approach, which is the approach you used in the above example is how I would go about doing it because i dont have to meddle with the middleware.

Jack
  • 48
  • 7
  • 4
    When using method 2) i am getting "Only static members can be accessed in initializers" – Monty Dec 27 '18 at 14:12
0

For this functionality you should extend CallableThunkAction<State> based on official docs:

An interface that can be implemented by end-users to create a class-based [ThunkAction].

Sample

class SigninAction extends CallableThunkAction<AuthState> {
  SigninAction(this.mobile);

  final String mobile;

  @override
  call(Store<AuthState> store) async {
    // call to server endpoint
    store.dispatch(results);
  }
}

then, dispatch it like:

store.dispatch(SigninAction('mobile number'));
Hamid Rasti
  • 813
  • 1
  • 6
  • 16