nayiaw
nayiaw

Reputation: 1456

Redux action ajax result not dispatched to reducer

I just get to experiment with Redux and I know that middleware is essential to make ajax calls. I've installed redux-thunk and axios package separately and tried to hook my result as a state and render the ajax result to my component. However my browser console displays an error and my reducer couldn't grab the payload.

The error:

Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.

This is part of my code and how the middleware is hooked up:

//after imports

const logger = createLogger({
  level: 'info',
  collapsed: true,
});

const router = routerMiddleware(hashHistory);

const enhancer = compose(
  applyMiddleware(thunk, router, logger),
  DevTools.instrument(),
  persistState(
    window.location.href.match(
      /[?&]debug_session=([^&]+)\b/
    )
  )

// store config here...

my action:

import axios from 'axios';

export const SAVE_SETTINGS = 'SAVE_SETTINGS';

const url = 'https://hidden.map.geturl/?with=params';
const request = axios.get(url);

export function saveSettings(form = {inputFrom: null, inputTo: null}) {
  return (dispatch) => {
    dispatch(request
      .then((response) => {
        const alternatives = response.data.alternatives;
        var routes = [];
        for (const alt of alternatives) {
          const routeName = alt.response.routeName;
          const r = alt.response.results;
          var totalTime = 0;
          var totalDistance = 0;
          var hasToll = false;
          // I have some logic to loop through r and reduce to 3 variables
          routes.push({
            totalTime: totalTime / 60,
            totalDistance: totalDistance / 1000,
            hasToll: hasToll
          });
        }
        dispatch({
          type: SAVE_SETTINGS,
          payload: { form: form, routes: routes }
        });
      })
    );
  }
}

reducer:

import { SAVE_SETTINGS } from '../actions/configure';

const initialState = { form: {configured: false, inputFrom: null, inputTo: null}, routes: [] };

export default function configure(state = initialState, action) {
  switch (action.type) {
    case SAVE_SETTINGS:
      return state;
    default:
      return state;
  }
}

you can see the state routes has size of 0 but the action payload has array of 3.

my latest action

Really appreciate any help, thanks.

Upvotes: 0

Views: 223

Answers (1)

It looks like you have an unnecessary dispatch in your action, and your request doesn't look to be instantiated in the correct place. I believe your action should be:

export function saveSettings(form = { inputFrom: null, inputTo: null }) {
  return (dispatch) => {
    axios.get(url).then((response) => {
      ...
      dispatch({
        type: SAVE_SETTINGS,
        payload: { form: form, routes: routes }
      });
    });
  };
}

Upvotes: 4

Related Questions