Reputation: 601
I have application, which fetches data from the server, which is written in nodeJS.
Using componentDidMount
i fetch the data. On page is input for name a table with data and every row has checkbox. When I click on button 'send', selected rows are send on backend. On backend I validate unique name. If is not, I return error. But fronted is every time refreshed. And is not possible get error message.
import React, {Component} from 'react';
import axios from 'axios';
import MyNavbar from "./MyNavbar";
class Offer extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleCheckedOrder = this.handleCheckedOrder.bind(this);
this.state = {
offers: [],
name: '',
selectedFoods: [],
selectedBuild: 'Nevybráno',
isOrderChecked: false
};
}
componentDidMount() {
this.getOffer();
}
getOffer() {
const url = '/offer';
axios.get(url).then(response => {
this.setState({offers: response.data})
}).catch(() => 'Cannot load menu');
};
handleNameChange = evt => {
this.setState({name: evt.target.value});
};
handleChecboxChange = offer => {
if (this.state.selectedFoods.includes(offer)) {
this.setState({selectedFoods: this.state.selectedFoods.filter(item => item !== offer)});
} else {
this.setState({selectedFoods: [...this.state.selectedFoods, offer]});
}
};
handleCheckedOrder() {
this.setState({isChecked: !this.state.isChecked});
}
isValid() {
let isEnabledSubmit = this.state.name.length > 0;
let isSelectedFoodAndNotOnlySoap = this.state.selectedFoods.length > 0 && this.state.selectedFoods.some(food => food.index !== 0);
let isSelectedBuild = this.state.selectedBuild !== 'Nevybráno';
return isEnabledSubmit && isSelectedFoodAndNotOnlySoap && isSelectedBuild;
}
handleSubmit() {
axios({
method: 'post',
url: '/order',
headers: {},
data: {
name: this.state.name,
food: this.state.selectedFoods,
order: this.state.isChecked,
build: this.state.selectedBuild
}
});
};
render() {
const {offers} = this.state;
const options = ["Nevybráno", "A", "B"];
return (
<div>
<MyNavbar/>
<div className="container">
<form className="form-inline justify-content-center" onSubmit={this.handleSubmit}>
<table className="table">
<tbody>
<tr>
<th> </th>
<th>#</th>
<th>Váha</th>
<th>Menu</th>
<th>Cena</th>
</tr>
{offers.map((offer) => {
return (
<tr key={offer.index}>
<td style={{width: '5%'}}>
<input type="checkbox" className="checkbox"
onChange={this.handleChecboxChange.bind(this, offer)}/>
</td>
<td style={{width: '5%'}}>{offer.index}</td>
<td style={{width: '10%'}}>{offer.weight}g</td>
<td style={{width: '70%'}}>{offer.name}</td>
<td style={{width: '20%'}}>{offer.discount} Kč</td>
</tr>
)
})}
</tbody>
</table>
<label className="sr-only" htmlFor="inlineFormInput">Name</label>
<input type="text" className="form-control mb-2 mr-sm-2 mb-sm-0" id="inlineFormInput"
placeholder="Jméno" onChange={this.handleNameChange}/>
<label className="mr-sm-2" htmlFor="inlineFormCustomSelect">Budova</label>
<select className="custom-select mb-2 mr-sm-2 mb-sm-0" id="inlineFormCustomSelect"
onChange={(e) => this.setState({selectedBuild: e.target.value})}>
{options.map(option => {
return <option value={option} key={option}>{option}</option>
})}
</select>
<div className="form-check mb-2 mr-sm-2 mb-sm-0">
<label className="form-check-label">
<input className="form-check-input" type="checkbox"
onChange={this.handleCheckedOrder}/> Objednám
</label>
</div>
<button type="submit" className="btn btn-secondary"
disabled={!this.isValid()}>Odeslat
</button>
</form>
</div>
</div>
);
}
}
export default Offer;
Upvotes: 1
Views: 416
Reputation: 2786
Try to add it in the form submit function evt.preventDefault();}
handleSubmit=(eve)=>
{
evt.preventDefault();
}
Tell me if it works or not.
Upvotes: 0
Reputation: 465
In addition to what maartendev's comment, to get the errors and result in component state you can write the handler as:
handleSubmit(evt) {
evt.preventDefault();
axios({
method: 'post',
url: '/order',
headers: {},
data: {
name: this.state.name,
food: this.state.selectedFoods,
order: this.state.isChecked,
build: this.state.selectedBuild
}
}).catch(({ response }) => this.setState({ errors: response.data }));
}
This will give you errors in this.state.errors which can be used in render method.
Upvotes: 2
Reputation: 5802
This is because the button submits the form and refreshes the page by default. This can be prevented by using evt.preventDefault();
handleSubmit(evt) {
evt.preventDefault();
axios({
method: 'post',
url: '/order',
headers: {},
data: {
name: this.state.name,
food: this.state.selectedFoods,
order: this.state.isChecked,
build: this.state.selectedBuild
}
});
};
Upvotes: 4