brianegan / redux_thunk

Redux Middleware for handling functions as actions
MIT License
88 stars 8 forks source link

Support callable classes as ThunkActions #12

Closed LRNZ09 closed 4 years ago

LRNZ09 commented 5 years ago

This would be really useful when you need a payload within your ThunkAction.

For example this function:

void GetShortenedUrlAction(Store<AppState> store) async {
  final String url = "http://example.com";
  final int seconds = 1;

  final String shortenedUrl = await Future.delayed(
    Duration(seconds: seconds),
    () => "http://tinyurl.com/yvdle",
  );

  store.dispatch(SetShortenedUrlAction(shortenedUrl: shortenedUrl));
}

It needs url as a param, and could have even some more.

How it could be:

class GetShortenedUrlAction {
  final String url;
  final int timeout;
  // ... etc

  GetShortenedUrlAction({this.url, this.timeout /* ... etc */});

  call(Store<AppState> store) async {
    final int seconds = 1;

    final String shortenedUrl = await Future.delayed(
      Duration(seconds: seconds),
      () => "http://tinyurl.com/yvdle",
    );

    store.dispatch(SetShortenedUrlAction(shortenedUrl: shortenedUrl));
  }
}

The middleware should check the action like this:

if (action.call is ThunkAction<State>) { /* ... */ }
jimsimon commented 5 years ago

I'm pretty sure this would be a potential solution for #11 as well (assuming the issue reporter there is okay with using classes).

brianegan commented 5 years ago

Ah, yes you're right. This used to be supported out of the box in Dart 1 (callable classes would actually pass the is check without needing to verify action.call), but I forgot to support this for Dart 2. I'll add it in :)

jimsimon commented 5 years ago

I'm curious to see your solution. I wasn't able to figure out if a object is callable or not without resorting to mirrors. Using action.call is ThunkAction<State> fails when an action that doesn't define a call function hits the middleware. I ended up using an abstract class and making my callable actions extend it.