I'm having trouble wrapping my head around how to handle api calls as a result of updates to data only the store should know how to perform (business logic). The basic flow is as follows:
AdComponent#_changeGeoTargeting
calls the action creator
UnpaidIntents#updateTargeting
which dispatches an
ActionTypes.UPDATE_TARGETS
action which is handled like so:
AdStore.dispatchToken = Dispatcher.register(action => {
switch(action.type) {
case ActionTypes.UPDATE_TARGETS:
// Business logic to update targeting from an action payload.
// `payload` is an object, e.g. `{ geos: geos }`, `{ devices: devices }`,
// etc.
_unpaid.targeting = _calcTargeting(
_unpaid.targeting, action.payload);
// Ajax call to fetch inventory based on `Ad`s parameters
WebAPIUtils.fetchInventoryPredictions(
_unpaid.start, _unpaid.end, _unpaid.targeting)
.then((resp) => {
var key = _makeCacheKey(
_unpaid.start, _unpaid.end, _unpaid.targeting);
// Updates store's inventory cache
_updateInventoryCache(key, resp);
})
.catch((error) => {
// How can I handle this error? If this request
// was executed inside an action I could have my
// `NotiticationsStore` listening for
// `ActionTypes.INVENTORY_PREDICTIONS_ERROR`
// and updating itself, but I can't dispatch here.
});
break;
default:
return true;
}
AdStore.emitChange();
return true;
});
The problem being that this call can't dispatch other actions since it's in a store.
I could make the call in the action creator, but that requires it to know how
to update the Ad
. I was under the impression that action creators should
be dumb "dispatcher helper methods", and something like this would violate those
principles:
UnpaidIntents.updateTargeting = (ad, value) => {
var targeting = _calcTargeting(ad.targeting, value);
WebAPIUtils.fetchInventoryPredictions(ad.start, ad.end, targeting)
.then((resp) => {
Dispatcher.dispatch({
type: ActionTypes.UPDATE_TARGETING,
payload: {
targeting: targeting,
inventory: resp,
},
});
})
.catch((error) => {
Dispatcher.dispatch({
type: ActionTypes.INVENTORY_PREDICTIONS_ERROR,
payload: error,
});
});
};
Would breaking out _calcTargeting
into an AdUtils
module and using that as
my business logic layer be the way to do this? I'm afaid if I have business
logic in utils and possibly also stores that things will get messy very quickly.
Can anyone give some guidance here?