Hey sorry I'm completely new to React and Javascript and I'm really confused about this. I'm trying to create a section where I will have a dropdown list in React. I have already fetched the data from Flask and now when I click my chosen option, I want to send the POST request to Flask (without clicking any submit button).
I was reading different answers and trying to figure it out so I used "fetch" while getting the data and "axios" when trying to send the request.
App.js
import React, { useEffect, useState } from "react"
import { DropdownItem } from "../Components/DropdownItem"
import Select from "react-select"
import axios from "axios"
export const DropdownPage = () => {
const [years, setYears] = useState([])
const [selectedYear, setSelectedYear] = useState("")
useEffect(() => {
fetch("http://127.0.0.1:5000/api", {
method: "GET",
headers: {
"Content-type": "application/json",
},
})
.then((res) => res.json())
.then((data) => {
setYears(data)
})
}, [])
const handleDropdownSelectYear = (e) => {
setSelectedYear(e.target.value)
}
const handleDropdownSubmitYear = (e) => {
e.preventDefault()
console.log(e)
axios
.post("http://127.0.0.1:5000/api/yearselect", selectedYear)
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
}
return (
<div>
<form method="post" onSubmit={handleDropdownSubmitYear}>
<select onChange={handleDropdownSelectYear}>
<option value="">Select Year</option>
{years.map((year) => (
<DropdownItem key={year.id} year={year}></DropdownItem>
))}
</select>
</form>
</div>
)
}
api.py
class Year(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.Text, nullable=False)
def __str__(self):
return f'{self.id} {self.content}'
def year_serializer(year):
return {'id': year.id,
'content': year.content}
@app.route('/api', methods=['GET'])
def index():
return jsonify([*map(year_serializer, Year.query.all())])
@app.route('/api/yearselect', methods=['POST'])
def yearselect():
if request.method == 'POST':
request_data = request.get_json(force=True)
year = Year(content=request_data['content'])
db.session.add(year)
db.session.commit()
return {"201": request_data['content']}
If there's any other information/code you need, please let me know. Also, I'm planning to recreate this image below. So, when I make my selection on the first dropdown, it should send a request to flask and narrow down the options for the next dropdown and so on. Let me know if you need any clarification. Thanks!!
CodePudding user response:
If you want to send the POST request when a selection is made, you don't need a <form>
or a submit handler.
Instead, add an effect hook that listens for changes to selectedYear
// if selectedYear is going to be an object, don't initialise it as a string
const [selectedYear, setSelectedYear] = useState();
useEffect(() => {
if (selectedYear) {
fetch("http://127.0.0.1:5000/api/yearselect", {
method: "POST",
body: JSON.stringify(selectedYear),
headers: { "content-type": "application/json" },
})
.then((res) => {
if (!res.ok) return Promise.reject(res);
return res.json();
})
.then((data) => {
// do something with data ¯\_(ツ)_/¯
})
.catch(console.error);
}
}, [selectedYear]); // effect hook dependencies
Effect hooks also run when the value is initialised so checking the value of selectedYear
before making the request is advisable.
The Axios equivalent would be
axios.post("http://127.0.0.1:5000/api/yearselect", selectedYear)
.then(({ data }) => {
// do something with data
})
.catch(err => {
console.error(err.toJSON());
});