dagatsoin
dagatsoin

Reputation: 2656

How to dispatch an action from a service unaware of Redux?

Say I have a geolocation service that is not aware of Redux and I configure it like this:

backgroundGeoLocation.configure(
  callback // will be called with an argument when the coordinates change
);

What is the cleanest way to make the service callback dispatch a Redux action without exporting store from a separate module and using store.dispatch() (because this would be a singleton)?

Upvotes: 10

Views: 8121

Answers (2)

ZigGreen
ZigGreen

Reputation: 178

If you don't want to callbackFn be aware of store.dispatch then you must create something like event stream or Observable from callbackFn. And once you have done you simply map the stream to store.dispatch function.

You're free to use any lib for creating streams but i recommend Rx

In that approach you'll must come with something like:

var geoLocation$ = new Rx.Subject();
var newCoordinatesAction = coordinates => ({
    type: "YOUR_TUPE", 
    payload: coordinates 
});
geoLocation$.map(newCoordinatesAction).map(store.dispatch);
backgroundGeoLocation.configure(::geoLocation$.onNext);

Upvotes: 2

Dan Abramov
Dan Abramov

Reputation: 268265

If you want to pass some value to some piece of code in JavaScript, you need to use functions.
For example,

function createGeoLocationService(store) {
  let backgroundGeoLocation = new BackgroundGeoLocation()
  backgroundGeoLocation.configure(coordinates => {
    store.dispatch({ type: 'UPDATE_COORDINATES', coordinates })
  })
  return backgroundGeoLocation
}

Now, wherever you create the store, create that service:

let store = createStore(reducer)
let backgroundGeoLocation = createGeoLocationService(store)

If you need to access it in the components, you can either:

  1. Make it a singleton (yup, not what you wanted, but it’s a valid option for client-only apps)
  2. Pass it down explicitly via props (can get tedious but it’s the most straightforward and explicit way)
  3. Pass it down implicitly via context (very easy but you will be dealing with an unstable API that is subject to change so it’s on your conscience)

Upvotes: 15

Related Questions