0

I have successfully written some code that will go through the redux flow, after the click of a button it will display the information I want on the UI.

I am using the este stack.

This is my button:

const Buttons = ({ requestAsyncData}) => (
  <View>
    <Button onClick={requestAsyncData}>
      <FormattedMessage {...buttonsMessages.add100} />
    </Button>
  </View>
);

export default connect(state => ({}), { requestAsyncData })(Buttons);

Now here is where I define the action:

export const REQUEST_ASYNC_DATA = 'REQUEST_ASYNC_DATA';

export const requestAsyncData = () => {

  return {
    type: REQUEST_ASYNC_DATA,
    payload: [{
      name: "one one!",
      id: Math.random()
    },{
      name: "two two!",
      id: Math.random()
    }]
  }

Here is my reducer:

const State = Record({
  map: Map()
}, "names");

const asyncExampleReducer = (state = new State(), action) => {
  switch (action.type) {

    case actions.REQUEST_ASYNC_DATA: {
      const names = action.payload.reduce((names, json) =>
          names.set(json.id, new Name(json))
        , Map());
      return state.update('map', map => map.merge(names));
    }

    default:
      return state;

  }
};

export default asyncExampleReducer;

This works exactly as expected on the ui, updating with the correct information, from the action, I get actual payload to do as I please:

payload: [{
  name: "one one!",
  id: Math.random()
},{
  name: "two two!",
  id: Math.random()
}]

Now I'm trying to make this payload asynchronous, let's say I will get the information for that object from an ajax api call.

How should I go about it?

I'm not sure if I need to go with thunks or if I should do something like suggested here, I've been trying all sort of recommendations but I'm not sure if my problems are javascript concrete problems or understanding react.

For example I've tried to do an action similar to the one suggested by thunk but it doesn't recognize dispatch and it doesn't seem to delay it either...

function doIncrementAction() {
  return {
    type: REQUEST_ASYNC_DATA,
    payload: [{
      name: "trufa!",
      id: Math.random()
    },{
      name: "benja!",
      id: Math.random()
    }]
  }
}

export const requestAsyncData = () => {
  return dispatch => {
      setTimeout(() => {
        // Yay! Can invoke sync or async actions with `dispatch`
        dispatch(doIncrementAction());
      }, 1000);
    };
};

raven.js:290 Uncaught TypeError: Cannot read property 'payload' of undefined

raven.js:290 Uncaught TypeError: dispatch is not a function

How should I go about this? Thanks!!

Trufa
  • 39,971
  • 43
  • 126
  • 190
  • 1
    Have you had a look at [Sagas](https://github.com/yelouafi/redux-saga/)? They're a way of tying in API calls (and other async operations) to the Redux data flow. – christopher Oct 02 '16 at 19:55
  • @christopher I haven't but I will now. Thanks – Trufa Oct 02 '16 at 19:56
  • They use some ES6 concepts so you'll need a transpiler, but I've found them to be an incredibly clean approach to doing asynchronous operations within a Redux framework. – christopher Oct 02 '16 at 19:57
  • Thunks are a good approach too. Sagas, sure, but thunks are good enough to handle any async ops with redux... did you forget to add the thunk middleware? – azium Oct 02 '16 at 20:06
  • @azium I'm pretty new to this, I'm pretty sure I did not add it correctly, I just did the: `import ReduxThunk from 'redux-thunk'` but nothing else, this looks relevant, I might be missing very obvious first steps since I don't know exactly what adding the thunk middleware implies. Thanks! – Trufa Oct 02 '16 at 20:13
  • 1
    I just answered a similar question there with a jsfiddle sample using redux-thunk; http://stackoverflow.com/questions/39813984/how-to-fetch-data-through-api-in-redux/39821184#39821184 – cdagli Oct 02 '16 at 20:13
  • This is how you add the middleware: http://redux.js.org/docs/advanced/AsyncActions.html#indexjs – bjudson Oct 02 '16 at 23:38
  • @bjudson I thought that's what I'm doing on the last code example, or am I not? I may have a concrete mistake though... I'm a little lost, the errors are not particularly helpful. – Trufa Oct 02 '16 at 23:47
  • @Trufa sorry, there is a lot of code there; specifically I was referring to the `redux.applyMiddleware()` call in `redux.createStore()`. You haven't posted your `createStore()` call here, so I can't tell if you are doing that part correctly. – bjudson Oct 03 '16 at 15:31

1 Answers1

0

The issue sounds like you haven't actually installed the redux-thunk middleware:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';

// Note: this API requires redux@>=3.1.0
const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);

After setting up your store like that, your example should work.

paulwithap
  • 678
  • 1
  • 7
  • 12