markdalgleish / redial

Universal data fetching and route lifecycle management for React etc.
1.1k stars 42 forks source link

Add support for plain callbacks #22

Open vesparny opened 8 years ago

vesparny commented 8 years ago

I'm not using Promises for http requests in my project, basically because I want to have the chance to cancel ongoing requests, so I tweaked redial making it able to support plain old callbacks.

In my fork you can see what I changed (please note it's just a prototype) https://github.com/vesparny/redial/blob/cb/src/trigger.js

That change allows hooks like:

const hooks = {
  fetch: ({dispatch}) => (callback) => dispatch(actions.load(callback))
}

dispatching a thunk, that invokes the callback when data has been loaded.

// actions.js
export const load = (callback) => {
  return createRequestAction({
    type: 'LOAD',
    method: 'GET',
    url: 'http://eu.httpbin.org/ip'
  }, callback)
}
// createRequestAction.js

import sendRequest from './sendRequest'

const defaultTypes = ['REQUEST', 'SUCCESS', 'ERROR']

export default (config, callback) => (dispatch) => {
  const typeSuffixes = config.typeSuffixes || defaultTypes
  const [REQUEST, SUCCESS, ERROR] = (config.typeSuffixes || {}).typeSuffixes || typeSuffixes

  dispatch({
    type: `${config.type}_${REQUEST}`,
    meta: config
  })

  // the thunk returns the request, so I can abort it if needed
  return sendRequest(config, (err, res) => {
    if (err || !res.ok) {
      dispatch({
        type: `${config.type}_${ERROR}`,
        err: true,
        payload: err,
        meta: config
      })
    } else {
      dispatch({
        type: `${config.type}_${SUCCESS}`,
        meta: {...config, status: res.status},
        payload: res.body
      })
    }
    if (typeof callback === 'function') {
      callback(err)
    }
  })
}

The implementation allows me to use superagent rather than other http clients Promise based.

I'm not sure this is something worth considering,but it's working pretty well for me and I wanted to share with you to get your feedback.

Thanks

markdalgleish commented 8 years ago

Sorry, finally got around to having a proper look at this. It looks like a pretty straightforward change. Would you like to submit a PR with tests for this?

kbzak commented 8 years ago

Just want to say that this feature helps with integrating redial with something like https://github.com/jeffbski/redux-logic - thanks for sharing, @vesparny!