The error for project is Error: Actions must be plain objects. Use custom middleware for async actions. and i want to know hot to resolve this problem. This is Store.js where put config history and store for before pass to the router
import {applyMiddleware , createStore, combineReducers, compose} from 'redux'
import {browserHistory} from 'react-router'
import {syncHistoryWithStore, routerReducer , routerMiddleware} from 'react-router-redux'
import {composeWithDevTools} from 'redux-devtools-extension';
import promise from "redux-promise-middleware"
import { createBrowserHistory } from 'history';
import exercise from './reducers/Exersice'
var reducers = {exercises:exercise};
const store = createStore(combineReducers({
...reducers,
routing: routerReducer
}), composeWithDevTools( applyMiddleware( routerMiddleware( createBrowserHistory() ), promise() ) ) )
const history = syncHistoryWithStore(createBrowserHistory(), store)
module.exports = {
store,
history,
reducers:()=>{
var exercises = require('./reducers/Exersice');
var reducers = {exercises:exercises};
return combineReducers({
...reducers,
routing: routerReducer
})
}
}
And this is the action file:
//Actions for get courses
import axios from 'axios'
//Get courses by author
export function getExerciseById(author){
return (context, id) => {
return {
type: 'GET_EXERCISE_ID',
payload: axios.get(window.url_api+'/exercises/'+id,
{headers:{'Authorization':'Bearer '+context.props.token}}),
}
}
}
export function getExercises(){
return (context, author) => {
return {
type: 'GET_EXERCISES',
payload: axios.get(window.url_api+'user'),
}
}
}
And this is my reducer
export default(state = {}, action) => {
switch (action.type){
case 'GET_EXERCISE_ID':
return {
...state,
fetching:false,
fetched: true,
data: action.payload
}
break;
case 'GET_EXERCISES':
return {
...state,
fetching:true,
fetched: false,
data: action.payload
}
break;
default:
return state
}
return state
}
And this is my router:
import React, {Component} from 'react';
import App from './Components/App';
import {Provider} from 'react-redux'
import Program from './routes/Programs/Program';
import Exercise from './routes/Exercise/Exercise';
import Generations from './routes/Generations/Generation';
import Routines from './routes/Routines/Routine';
import Promos from './routes/Promos/Promo';
import Logout from './routes/Logout';
import {
BrowserRouter as Router,
Route
} from 'react-router-dom';
module.exports = (store, history) => {
return (
<Provider store={store}>
<Router history={history}>
<div>
<Route path="/" component={App} />
<Route path="/home" component={App}/>
<Route path="/generaciones" component={Generations}/>
<Route path="/rutinas" component={Routines}/>
<Route path="/ejercicios" component={Exercise}/>
<Route path="/promociones" component={Promos}/>
<Route path="/cerrarsesion" component={Logout}/>
</div>
</Router>
</Provider>
)
}
A little vocabulary lesson is in order first. The action is the object you are sending. The action creator is the function that, well, creates the action. You can't put async code inside your action itself. The request needs to made inside the action creator function, but not the action object.
You signal to redux that you are going to use async code by returning an anonymous function that takes the dispatch argument. The dispatch callback is then passed into your anonymous function, and you use it to send the action object to the state store.
You have:
export function getExerciseById(author){
return (context, id) => {
return {
type: 'GET_EXERCISE_ID',
payload: axios.get(window.url_api+'/exercises/'+id,
{headers:{'Authorization':'Bearer '+context.props.token}}),
}
}
}
Change it to:
export function getExerciseById(author){
return function(dispatch) {
axios.get(window.url_api+'/exercises/'+id, {headers:{'Authorization':'Bearer '+context.props.token}})
.then(response => {
dispatch({
type: 'GET_EXERCISE_ID',
payload: response.data
})
})
}
}
Or, use async and await
export const getExerciseById = author => async dispatch => {
try {
let response = await axios.get(window.url_api+'/exercises/'+id, {headers:{'Authorization':'Bearer '+context.props.token}});
dispatch({
type: 'GET_EXERCISE_ID',
payload: response.data
});
} catch (err) {
console.log(err);
}
}