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)?
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)?
2 Answers
Reset to default 15If 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:
- Make it a singleton (yup, not what you wanted, but it’s a valid option for client-only apps)
- Pass it down explicitly via props (can get tedious but it’s the most straightforward and explicit way)
- 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)
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);