1

I would like to display the error to my user. An error is thrown and the error and message are updated in the reducer by the action. But for some reason I can't get the error or message to display for the user. Is there something wrong with the reducer or mapStateToProps? How does the component know the state has been updated? I'm not sure how to update that.....

What am I missing?

reducer:

import {CREATE_VEHICLE,VEHICLE_ERROR, 
VEHICLE_FORM_PAGE_SUBMIT,FETCH_VEHICLES_SUCCESS} from '../actions/vehicles';

const initialState={message: null, error: null, vehicle:{}};

 export default function vehicleReducer(state=initialState, action) {
console.log("in reducer");
switch(action.type){
case CREATE_VEHICLE:
    return [...state, Object.assign({}, action.vehicle, action.message)];
case VEHICLE_ERROR:
    return{
    ...state,
        error: action.error,
        message: action.message
    };
    default:
        return state;
}
}

actions:

export const vehicleError = (error, msg) => {
return{
type: VEHICLE_ERROR,
error:error,
message: msg
}

};

export const createVehicle=(vehicle) =>{
console.log("vehicle: ", vehicle);

return (dispatch) => {
    return axios.post(`http://localhost:9081/api/bmwvehicle/create`, 
vehicle)

    .then((response) =>{
        if (response.ok){
            console.log("success");
             dispatch(createVehicleSuccess(response.data))

        }}, (error) => {
                if (error.response.status == 500){
                dispatch(vehicleError(error.message, "Could not add vehicle, 
please try again."));

            }

        }
    );
};};

component:

class Vehicle extends React.Component{
 constructor(props){
        super(props);
      }


      submitVehicle(input){
        this.props.createVehicle(input);
        }

      render(){
          console.log("the error is: ",this.props.error);
            return(
                    <div>
                        <AddVehicle submitVehicle= 
{this.submitVehicle.bind(this)} /> 
                    </div>

                )
      }
}

      const mapStateToProps=(state, ownProps) => {
          return{
              vehicle: state.vehicle,
              message: state.message,
              items: state.items,
              vehicles: state.vehicles,
              error: state.error
          }
      };

      const mapDispatchToProps=(dispatch)=>{
          return {
              createVehicle: vehicle => 
dispatch(vehicleActions.createVehicle(vehicle))
          }
      };


export default connect(mapStateToProps, mapDispatchToProps)(Vehicle);
Roro
  • 297
  • 5
  • 17
  • It's great that you have included most of the relevant code, but I recommend also creating a minimal code sandbox (https://codesandbox.io/) that is actually a working react app. Instead of the api call, just have two buttons, one to dispatch the createVehicleSuccess action with hard-coded data and one to dispatch vehicleError with hard-coded error info. Then you can point to this in your post and someone can help point out/fix the error much more quickly. – Ryan Cogswell Nov 14 '18 at 21:59
  • I think your problem is that if the response status code is not 500 you discard the error. I think it's better to call vehicleError if there's error. – boaz_shuster Nov 14 '18 at 22:01

1 Answers1

1

In your CREATE_VEHICLE action, i think you meant to return the state with curly braces instead? {...state, Object.assign({}, action.vehicle, action.message)}

In your mapStateToProps, you attempt to access state.vehicles and state.items, but it does not exist in your default initial state const initialState={message: null, error: null, vehicle:{}}.

To answer your question about how does the component know the (redux) state has been updated, the component knows because you wrapped it in the Redux HoC called connect() which will notify your component via an update anytime the mapped redux state changes. In your case, the component will be updated on changes to the redux store's state.vehicle, state.message, state.items, state.vehicles and state.error.

Shawn Andrews
  • 1,322
  • 10
  • 21