joshburgess / redux-most

Most.js based middleware for Redux. Handle async actions with monadic streams & reactive programming.
https://www.npmjs.com/package/redux-most
MIT License
139 stars 14 forks source link

Add the ability to inject a custom argument into Epics #19

Open joshburgess opened 7 years ago

joshburgess commented 7 years ago

Possible Feature: Add the ability to inject a custom argument into Epics

Consider adding the ability to inject a custom argument into Epics to give access to an API utility or similar dependency, like currently possible with redux-thunk and redux-observable.

We will need to consider how we handle https://github.com/joshburgess/redux-most/issues/4 when implementing this.

joshburgess commented 7 years ago

Examples

in redux-thunk:

https://github.com/gaearon/redux-thunk#injecting-a-custom-argument

in redux-observable:

https://redux-observable.js.org/docs/recipes/InjectingDependenciesIntoEpics.html

joshburgess commented 7 years ago

@jshthornton We should think about this also when considering the withStore and withState$ higher order functions we talked about.

mcky commented 6 years ago

@joshburgess Wow, I was just putting together an example to go with a proposal to add this, and I see It's already here!

Looking at the implementation of thunks and redux-observables, this seems fairly easy to add, would you be able to elaborate as to why it's a breaking change?

joshburgess commented 6 years ago

Hi, @mcky

I marked it as a breaking change, because it directly affects the Epic API, and we've been talking about possibly rearranging the order of arguments.

Right now, as of the the last major update, there are two ways to use redux-most. See this section taken from the docs:

redux-most offers 2 separate APIs: a redux-observable-like API, where Epics get passed an action stream & a store middleware object containing dispatch & getState methods, and a stricter, more declarative API, where Epics get passed an action stream & a state stream.

...

Initially, redux-most offered the same API as redux-observable, where Epics received an action stream & a store middleware object containing dispatch & getState methods. However, it now offers both that API and another stricter, more declarative API which eliminates the use of dispatch & getState. The reason for this is that I rarely found myself using the imperative dispatch method. It's not really needed, because you can use switch, merge, mergeArray, etc. to send multiple actions through your outgoing stream. This is nice, because it allows you to stay locked into the declarative programming style the entire time.

However, using getState was still required in epics that needed access to the current state. I wanted a nice, convenient way to access the current state, just like I had for dispatching actions. So, I created an alternate API where Epics receive a stream of state changes rather than the { dispatch, getState } object. This state stream, combined with the new withState utility function, let's you use streams for both dispatching actions & accessing the current state, allowing you to stay focused & in the zone (the reactive programming mindset).

So, we have both of those, and, I'm still considering reversing the argument order on each of them, or evolving the API so that there is only ever one type of Epic and you can modify which extra arguments (other than the action$) you need through higher order functions.

But I haven't narrowed down what the right course of action is yet, so I held off on adding this injecting dependencies feature, since I'm not sure the best way to make it fit in. It is, indeed, a pretty trivial thing to implement, but I'm still unsure about it in the context of changing argument orders, maybe using HOFs, etc....

See https://github.com/joshburgess/redux-most/issues/4 for more info on reversing the argument order & HOFs ideas.

Any ideas?