I'm new to React, sorry if this is too basic.
I have an input form and I'm trying to handle submits and changes to it, like so:
import { editMenuFormRules } from './forms/form-rules.js';
class Seeds extends Component{
constructor (props) {
super(props);
this.state = {
formData: {
coffee:''
},
menu:[],
editMenuFormRules:editMenuFormRules,
};
this.handleSubmitCoffees = this.handleSubmitCoffees.bind(this);
this.handleBeanFormChange = this.handleBeanFormChange.bind(this);
};
componentDidMount() {
if (this.props.isAuthenticated) {
this.getSeeds();
}
};
getSeeds(event) {
const {userId} = this.props
const options = {
url: `${process.env.REACT_APP_WEB_SERVICE_URL}/seeds/${userId}`,
method: 'get',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${window.localStorage.authToken}`
}
};
return axios(options)
.then((res) => {
console.log(res.data.data)
this.setState({
menu: res.data.data[0].menu
})
})
.catch((error) => { console.log(error); });
};
for handling submit and form change, I have:
handleSubmitCoffees(event) {
event.preventDefault();
const formType = this.props.formType
const {userId} = this.props
var headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${window.localStorage.authToken}`
}
const data = {
coffee: this.state.formData.coffee
};
if (formType === 'EditMenu' && this.state.menu.includes(this.state.formData.coffee)) {
alert('This coffee already exists. Please add a new one.');
return (<Redirect to='/seeds' />);
};
const url = `${process.env.REACT_APP_WEB_SERVICE_URL}/edit_menu/${userId}`;
axios.post(url, data, headers)
.then((res) => {
this.clearForm()
console.log(data);
})
.catch((err) => {
if (formType === 'EditCoffee') {
this.props.createMessage('Coffee edit failed.', 'Please review your entry');
};
});
};
and:
handleBeanFormChange(event) {
console.log(event)
const obj = this.state.formData;
obj[event.target.name] = event.target.value;
this.setState(obj);
this.validateForm();;
};
finally, my form:
<form onSubmit={ (event) => this.handleSubmitCoffees(event) }>
<div className="field">
<input
name="coffee"
className="input is-large"
type="text"
placeholder="Enter Coffee Name"
value={this.state.formData.coffee}
onChange={this.handleBeanFormChange}
/>
</div>
</form>
when I input my first item at form, however, I'm getting the following error:
TypeError: Cannot read property 'includes' of undefined
which points to this line:
> 150 | if (formType === 'EditMenu' && this.state.menu.includes(this.state.formData.coffee)) {
am I not defining this.state.formData.coffee
when I press enter at form?
What am I missing?
const obj = this.state.formData;
obj[event.target.name] = event.target.value;
this.setState(obj); // <-- this is setting 'target.name: value'
This is effectively overwriting formData
. I think what you are meaning to do is:
const obj = Object.assign({}, this.state.formData);
obj[event.target.name] = event.target.value;
this.setState({ formData: obj });
Do note that it's important to clone the formData
object, as what you are doing is mutating the state, which is not desired.
The problem is here, where there is a GET
request for 'menu' value:
componentDidMount() {
if (this.props.isAuthenticated) {
this.getSeeds(); ///// <------------
}
};
There was a malformed json
response object at backend:
response_object = {
'status': 'success',
'message': 'User does not have a menu yet',
'data': [{"id": user.id,
"seeds": user.seeds,
"content": template}]
}
//"menu": [] //----> key, value was missing
Therefore, there was no 'menu' value being fetched, and that's what 'undefined' refers to:
//GET request at `getSeeds()`
this.setState({
menu: res.data.data[0].menu // <----- undefined
})
no this.state.menu
could be set at getSeeds()
, at all.
Adding "menu": []
to response_object
fixed it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With