Reputation: 759
I have a React/Redux application using axios to make requests to an express backend.
I am trying to submit a form to the backend route /api/patients/outcomes/:id
- where :id
is the MongoDB ID for the specific patient whom the data in the form belongs to. On the backend the route adds the form data to an 'outcomes' array on the patient object.
I am having trouble getting the :id
into the onSubmit
function. When the component with the form is rendered, I have a patients
object in Redux that contains the patient's information from the database; the Redux state when component loads is as following:
Redux state
|
|-- patients
| |-- patients [list of all patients - irrelevent to this component]
| +-- patient {patient object}
| |-- _id
| |-- name
| +-- contactInfo {object with contact info}
|
|-- auth
| |-- isAuthenticated
| +-- user
|
+-- errors
I have mapped state to props, i've pulled the patient object out of props, i've bound the onSubmit function in the call and I have passed the patient._id
into the bind()
, however it does not carry to the onSubmit
function and thus isn't being passed into the redux action call and in turn not being assigned to the route mentioned above for the axios.post
request.
Can anyone see what I am doing wrong here - been at it for a few hours and have made no progress!
The React container that holds the form is as follows (I've truncated the HTML for convenience but it is fundamentally identical)
SubmitOutcome.js
// imports
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
// components
import Navbar from '../components/layout/Navbar';
import Sidebar from '../components/layout/Sidebar';
// redux actions
import { submitOutcomeMeasure } from '../redux/actions/patientActions';
class SubmitOutcome extends Component {
constructor() {
super();
this.state = { dateOfTesting: '', measure: '' };
}
// event handlers
onChange = e => {
this.setState({ [e.target.name]: e.target.value });
};
onSubmit = patient_id => e => {
e.preventDefault();
const outcomeData = {
dateOfTesting: this.state.dateOfTesting,
measure: this.state.measure
};
this.props.submitOutcomeMeasure(outcomeData, patient_id, this.props.history);
};
render() {
const { patient } = this.props.patients;
return (
<>
<Navbar />
<div className="app-body">
<Sidebar />
<main className="main">
<div className="container">
<form onSubmit={this.onSubmit.bind(this, patient._id)}>
<div>
<input
type="date"
name="dateOfTesting"
value={this.state.dateOfTesting}
onChange={this.onChange}
/>
<input
type="text"
name="measure"
value={this.state.measure}
onChange={this.onChange}
/>
</div>
<div>
<Link to="/patients" className="btn btn-light mr-2">
Cancel
</Link>
<button type="submit" className="btn btn-primary">
Submit
</button>
</div>
</form>
</div>
</main>
</div>
</>
);
}
}
SubmitOutcome.propTypes = {
submitOutcomeMeasure: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
patients: state.patients
});
export default connect(
mapStateToProps,
{ submitOutcomeMeasure }
)(SubmitOutcome);
Relevant action from patientActions.js
export const submitOutcomeMeasure = (
outcomeData,
id,
history
) => dispatch => {
axios
.post(`/api/patients/outcomes/${id}`, outcomeData)
.then(res => {
history.push(`/portal/patients/${id}`);
})
.catch(err => {
dispatch({
type: GET_ERRORS,
payload: err.response.data
});
});
};
Upvotes: 0
Views: 1561
Reputation: 5177
first of all you are using fat arrow so you don't need to bind and you can try this line instead and see if it works .
<form onSubmit={e => this.onSubmit(e, patient._id)}>
and then change the onSubmit definition to look like this
onSubmit = (e, patient_id) => {
e.preventDefault();
const outcomeData = {
dateOfTesting: this.state.dateOfTesting,
measure: this.state.measure
};
this.props.submitOutcomeMeasure(outcomeData, patient_id, this.props.history);
};
and see if this works
Upvotes: 2