2

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
  }
}
Keslavi
  • 143
  • 3
  • 14

2 Answers2

1

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 }); }); } }

RIYAJ KHAN
  • 15,032
  • 5
  • 31
  • 53
  • U r returning promise in payload which need to be resolved to get the response data.instead just or simply do as i shown above. – RIYAJ KHAN Mar 04 '18 at 05:23
  • I'm using promise from redux-promise to handle the promise instead of redux-thunk and it's definately working, I just created another component page in which it worked; the reducer correctly processed return _.mapKeys(action.payload.data,'_id');. – Keslavi Mar 04 '18 at 06:31
  • @Keslavi could u please add some code how you are resolving the promise – RIYAJ KHAN Mar 04 '18 at 06:37
  • https://github.com/keslavi/react-auth. MERN created with create-react-app then a proxy in packages.json attaches to the express portion. Thank you so much for your patience! – Keslavi Mar 04 '18 at 07:36
  • @RIYAJKHAN please don't recommend `redux-saga` to people who only need simple async actions, I'd go with `thunk`. – timotgl Mar 04 '18 at 11:25
1

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.

Keslavi
  • 143
  • 3
  • 14
  • adding this for future reference if i do need a callback with a reducer: https://stackoverflow.com/questions/44325372/adding-a-callback-to-a-redux-reducer – Keslavi Mar 04 '18 at 16:32