Fantasim Fantasim - 22 days ago 27
React JSX Question

Error with redux-promise : Actions must be plain objects. Use custom middleware

I'm actually trying to use redux-promise, and when i send a request to my api in my action, i get this error.

enter image description here

I saw that there was a speaking subject to the same error but I have not found my problem solving in responses.

So this is my code :

./app.js

import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import { Router, browserHistory } from 'react-router'
import reducers from './reducers/app-reducer'
import routes from './routes'

import promise from 'redux-promise'

const createStoreWithMiddleware = applyMiddleware(promise)(createStore);


ReactDOM.render(<Provider store={createStoreWithMiddleware(reducers)}>
<Router history={browserHistory} routes={routes} />
</Provider>, document.querySelector('.container'))


./reducers/app-reducer.js

import { combineReducers } from 'redux'
import user from './user-reducer'


const rootReducer = combineReducers({
user: user
})

export default rootReducer





action whose called :

./actions/user-actions.js

import axios from 'axios'

export const UPDATE_TOKEN = 'UPDATE_TOKEN'
export const CREATE_SESSION = 'CREATE_SESSION'
export const CREATE_SESSION_ERROR = 'CREATE_SESSION_ERROR'

export function createSession(obj){

if (typeof obj === 'string') {

return {
type: UPDATE_TOKEN,
payload: obj
}
}
else {
axios.post('http://localhost:8080' + '/session', {
data: {'Email': obj.email, 'Password': obj.password},
headers: {'Content-Type': 'application/json'}
}).then((response) => {
return {
type: CREATE_SESSION,
payload: response.data
}
}).catch((error) => {
return {
type: CREATE_SESSION_ERROR,
payload: error
}
})
}
}


I've also tried with redux-thunk, I get the same error.

Someone you have an idea ? or maybe do I take me wrong?
Thanks

Answer

When creating ajax calls in actions, you should use redux-thunk and compose.

import {createStore, applyMiddleware, compose} from "redux";
import thunk from 'redux-thunk';

Change your store like this:

const createStoreWithMiddleware = compose(applyMiddleware(thunk))(createStore)(reducers);

And set axios to use dispatch:

return (dispatch) => {
   axios.post('http://localhost:8080' + '/session', {
      data: {'Email': obj.email, 'Password': obj.password},
      headers: {'Content-Type': 'application/json'}
   }).then((response) => {
      dispatch ({
         type: CREATE_SESSION,
         payload: response.data
      })
   }).catch((error) => {
      return {
         type: CREATE_SESSION_ERROR,
         payload: error
      }
   })
}