reactjsreact-reduxreact-redux-form

With redux-form, how to set initialValues based on an ASYNC redux state?


I'm using react redux-form. I'm working to create a React component to allow the user to edit their profile.

Here is how I am working to set the initalValues for redux-form:

import * as profilesActions from '../../actions/profilesActions';
....
const mapStateToProps = state => {
  return {
    currentUser: state.currentUser,
    currentUserProfile: state.profiles.find(el => el.id === state.currentUser.user_id),
    initialValues: {
      first_name: state.currentUserProfile.first_name,
      last_name: state.currentUserProfile.last_name
    }
  };
};

The problem is right now this is erring with:

Uncaught TypeError: Cannot read property 'first_name' of undefined

The reason is the user's profile has not yet been loaded into state.profiles...

How do I setup the initialValues to be set/updated when currentUserProfile changes?

Updated

profilesActions.js

import * as types from './actionTypes';
import ProfilesApi from '../api/ProfilesApi';

export function loadProfileSuccess(profile) {
  return {type: types.LOAD_PROFILE_SUCCESS, profile};
}

export function loadProfile(user_id) {
  return function(dispatch) {
    return ProfilesApi.loadProfile(user_id).then(profile => {
      dispatch(loadProfileSuccess(profile));
    }).catch(error => {
      throw(error);
    });
  };
}

actionTypes

export const LOAD_PROFILE_SUCCESS = 'LOAD_PROFILE_SUCCESS';

Updated

Here is my latest attempt:

export const LOAD_PROFILE_SUCCESS = 'LOAD_PROFILE_SUCCESS';

Profile = connect(
  state => ({
    initialValues: {
      first_name: state.currentUserProfile.first_name,
      last_name: state.currentUserProfile.last_name
    }
  }),
  { profilesActions: LOAD_PROFILE_SUCCESS }               // bind account loading action creator
)(Profile)

this is erring w bindActionCreators expected a function actionCreator for key 'profilesActions', instead received type 'string


Solution

  • The second argument of react-redux connect is a function with dispatch as a parameter (See the documentation here). The correct way to use would be something like the following:

    Profile = connect(
      state => ({
        initialValues: {
          first_name: state.currentUserProfile.first_name,
          last_name: state.currentUserProfile.last_name
        }
      }),
      dispatch => ({ profilesActions: dispatch({ type : LOAD_PROFILE_SUCCESS }) })
    )(Profile)