React Redux Action Payload returning undefined

5.2k views Asked by At

I'm trying to get my profile state into redux. the form and action are all working correctly but the action's payload is undefined when it goes to the reducer. Pretty sure it's a rookie mistake but I can't see it for the life of me.

I followed Stephen Grider's udemy course as a template and have his posts section working using exactly the same pattern applied to the login. redux-promise is wired up correctly in the middleware.

package.json (partial)

"react": "^16.2.0",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-form": "^7.2.3",
"redux-forms": "^1.0.0-3",
"redux-promise": "^0.5.3",

LoginComponent:

function mapStateToProps(state){
  return {
    profile:state.profile
  };
}

export default reduxForm({
  validate,
  form:'PostsNewForm'
})(
  connect(mapStateToProps,{login})(Login)
);

action-profile

export const profileActions = {
    login:'uaLogin',
    logout:'uaLogout',
    register:'uaRegister',
    getAll:'uaGetAll',
    getOne:'uaGetOne',
    delete: 'uaDelete'
};

const pa=profileActions;

export function login(values, callback){
  const request=axios.post(`/api/authenticate`,values)
    .then ((res)=> {
      console.log ('*** action:',res.data);//res.data  correctly appears
      callback()
    });
  return {
    type: pa.login,
    payload:request
  }
}

Reducer-profile

import {profileActions as pa} from '../actions';

let profile = JSON.parse(localStorage.getItem('profile'));
const initialState = profile ? { loggedIn: true, profile } : {};

export default function authentication(state = initialState, action) {
  switch (action.type) {
    case pa.login:
      console.log('***reducer',action.payload.data);//action.payload is undefined
      return {
        action.payload.data 
      };
    default:
      return state
  }
}
2

There are 2 answers

1
Keslavi On BEST ANSWER

the error is occuring because the .then statement is attached directly to the const request. This is resolving the promise and changing request to undefined.

Change This:

const request=axios.post(`/api/authenticate`,values)
  .then ((res)=> {
  console.log ('*** action:',res.data);//res.data  correctly appears
  callback()
});

To This:

const request=axios.post(`/api/authenticate`,values);

the second problem is that I'm trying to do perform an action in the form via the fallback and forgetting the react and redux paradigm; the callback in this case isn't needed.

instead I should look at componentDidMount or possibly componentWillMount and check the state to decide whether to navigate away.

5
RIYAJ KHAN On

There are some corrections :

  1. login is asynchronous action.User redux-thunk or redux-saga for dispatching async action.

  2. considering the above point,the right signature for login action.

export function login(values, callback) { return function (dispatch) { const request = axios.post(/api/authenticate, values) .then((res) => { console.log('*** action:', res.data);//res.data correctly appears callback(); //dispatch anothe action inside the async action.
dispatch({ type: pa.login, payload: res.data }); }); } }