mattkrick / redux-optimistic-ui

a reducer enhancer to enable type-agnostic optimistic updates
MIT License
693 stars 36 forks source link

Reducer not getting called after COMMIT/REVERT #5

Closed mwalsher closed 8 years ago

mwalsher commented 8 years ago

It seems the reducer isn't being called after an optimistic action is committed/reverted. Is this intentional? Or am I missing something? If I remove the optimistic value from meta, the reducer is called as expected.

Basically I am trying to set an error message in the event that an optimistic action fails. Looking at your meatier example, it seems that this should be possible?

Here is the relevant API code which dispatches the optimistic actions:

const [ requestType, successType, failureType ] = types

// Allow the requestType action to continue being dispatched
next(_actionWith(action, Object.assign({}, { type: requestType },
  optimistic ? { meta: { optimistic: { type: BEGIN, id: transactionId } } } : {}
)))

// Call the API
return _callApi(endpoint, schema, method, payload).then(
  // If successful, dispatch the successType action and COMMIT the optimistic transaction
  response => {
    let nextActionParams = _actionWith(action, Object.assign({}, { type: successType, payload: response },
      optimistic ? { meta: { optimistic: { type: COMMIT, id: transactionId } } } : {}
    ))
    return next(nextActionParams)
  },
  // If unsuccessful, dispatch the failureType action and REVERT the optimistic transaction
  error => {
    let nextActionParams = _actionWith(action, Object.assign({},
      { type: failureType, error: error.message || 'Something bad happened' },
      optimistic ? { meta: { optimistic: { type: REVERT, id: transactionId } } } : {}
    ))
    return next(nextActionParams)
  }
).catch(error => {
  debugger
})

function _actionWith (action, data) {
  const finalAction = Object.assign({}, action, data)
  delete finalAction.meta[API_CALL]
  return finalAction
}
mwalsher commented 8 years ago

It looks like historyWithoutRevert is empty when the revert is being applied, which I believe is why the reducer isn't being called.

mattkrick commented 8 years ago

So your callback adds an error message and ACTION_ERROR should put that in the state

On Mon, Feb 22, 2016, 10:29 PM Mike Walsh notifications@github.com wrote:

It looks like historyWithoutRevert is empty when the revert is being applied, which I believe is why the reducer isn't being called.

— Reply to this email directly or view it on GitHub https://github.com/mattkrick/redux-optimistic-ui/issues/5#issuecomment-187506811 .

mwalsher commented 8 years ago

That's exactly what is supposed to happen (and in fact does happen if I set optimistic: false to disable your reducer enhancer), however my ACTION_ERROR action isn't getting triggered when a REVERT occurs.

mwalsher commented 8 years ago

Changing your code as follows fixes the issue:

case COMMIT:
  let committedState = applyCommit(state, id, reducer)
  return committedState.set('current', reducer(committedState.get('current'), action))
case REVERT:
  let revertedState = applyRevert(state, id, reducer)
  return revertedState.set('current', reducer(revertedState.get('current'), action))
mattkrick commented 8 years ago

could you write a failing test case? I still think this is a middleware error instead of something wrong with the package

mattkrick commented 8 years ago

reading through this again, are you saying that you commit something and THEN revert it? If so then that's expected behavior. SUCCESS & ERROR are mutually exclusive

mattkrick commented 8 years ago

believe this is was an implementation problem, since the optimistic-ui result should be part of the action meta data & not an action itself