0

I am trying to understand if there is a way to call data from redux in an Action.

Here is my action where I want to use user_id and token which are stored in state.auth.user_id and state.auth.token

jobsActions.js

export function createJob(title, company, avatar, shortDescription, description, address, postcode, city, jobType, payment, price, duration, postDate ) {
  return function (dispatch) {
      return axios.post(JOBS_URL(user_id), { title, company, avatar, shortDescription, description, address, postcode, city, jobType, payment, price, duration, postDate }, {
        headers: { authorization: token }
      }).then((response) => {
        dispatch(addJob(response.data.job));
        // console.log(response.data.job)
      }).catch((err) => {
        // console.log(err);
        dispatch(addAlert("Couldn't create job."));
      });
  };
}

authAction.js

export function loginUser(email, password) {
  return function (dispatch) {
    return axios.post(SIGNIN_URL, { email, password }).then((response) => {
      var { user_id, token } = response.data;
      dispatch(authUser(user_id, token));
      onSignIn(user_id);
    }).catch((error) => {
      dispatch(addAlert("Could not log in."));
    });
  };
}

export const authUser = (user_id, token) => {
  return {
    type: 'AUTH_USER',
    user_id,
    token
  }
}
Markus Hayner
  • 2,869
  • 2
  • 28
  • 60
  • Possible duplicate of [Accessing Redux state in an action creator?](https://stackoverflow.com/questions/35667249/accessing-redux-state-in-an-action-creator) – Henrik Andersson May 13 '18 at 11:16
  • @HenrikAndersson Whats the duplicate in this? I have already dispatched the the user_id and token from authAction.js and now I need to use them in jobsAction.js see the edit – Markus Hayner May 13 '18 at 11:21
  • Exactly, you want to access your stores data inside an action creator, right? – Henrik Andersson May 13 '18 at 11:28

2 Answers2

0

Yes. You're using redux-thunk, and thunk functions already get getState as the second argument. Just change your functions to:

export function createJob(title, company, avatar, shortDescription, description, address, postcode, city, jobType, payment, price, duration, postDate ) {
  return function (dispatch, getState) {
      const state = getState();
      const {user_id, token} = state.auth;

      return axios.post(JOBS_URL(user_id), { title, company, avatar, shortDescription, description, address, postcode, city, jobType, payment, price, duration, postDate }, {
        headers: { authorization: token }
      }).then((response) => {
        dispatch(addJob(response.data.job));
        // console.log(response.data.job)
      }).catch((err) => {
        // console.log(err);
        dispatch(addAlert("Couldn't create job."));
      });
  };
}
markerikson
  • 63,178
  • 10
  • 141
  • 157
0

I had the same problem before and created an enhancer to help handle it:

redux-named-reducers

It allows state access from anywhere in your code and to link reducer states to each other. For example, using the enchancer your job reducer can have an read-only external state called token linked to your auth reducer's token:

linkState(jobReducer.token, authReducer.token)

Later you can access the token from your action

createJob() {
   ...
   var token = getState(jobReducer.token)
}

The advantage of this is your job module does not care where the token comes from. You can easily swap authentication methods from different modules:

swith(loginType) {
    case USERNAME_AND_PASSWORD:
       linkState(jobReducer.token, authReducer.token)
    break;
    case FACEBOOK_LOGIN:
       linkState(jobReducer.token, facebookReducer.token)
    break;
    case OAUTH:
       linkState(jobReducer.token, oauthReducer.token)
    break
}