9

I am a beginner.I am trying to implement a POST request from React.js in a simple form, but I cannot figure out how to send POST request to database. I guess I need <form action="URL"> as well. Any help will be appreciated. Below is the code from React.js(frontend)

import GameTestResult from './GameTestResult'; export default function App() { const[data, setData] = useState([]); const [formData, setFormData] = useState(""); useEffect (() => { fetch('http://localhost:3000/game') .then(res => res.json()) .then(result => setData(result.rows)) .catch(err => console.log("error")) },[]); const handleChange = event => { setFormData(event.target.value) } const eventHandler = event => { event.preventDefault(); setFormData(""); } return ( <div className="App"> <form method="post" onSubmit = {eventHandler}> <input value = {formData} onChange = {handleChange} /> <button type="submit">click</button> </form> {data && data.map((element, index)=>( <GameTestResult name = {element.name} key={element.index} /> ))} </div> ); } 

here is the code from express.js(backend)

var router = express.Router(); const pool = require("../config.js"); var cors = require('cors'); router.get("/game", cors(), (req, res) => { pool .query("SELECT * FROM game") .then((data) => res.json(data)) .catch((e) => { res.sendStatus(404), console.log(e); }); }); router.post("/game", (req, res) => { const { name } = req.body; pool .query('INSERT INTO game(name) values($1);', [name]) .then(data => res.status(201).json(data)) .catch(e => res.sendStatus(404)); }); module.exports = router; 
6
  • Yes, API works. I have no errors, Post request works in backend when I tested via Postman. Now I cannot do Post request in Form using React.js. In this code I have no error , but database is not populated after clicking Form ‘click’ button Commented May 24, 2020 at 13:41
  • Backend is in port 5000, and frontend in 3000 port and works fine Commented May 24, 2020 at 13:42
  • API is called correctly, I can at least show GET request in React.js Commented May 24, 2020 at 14:00
  • What's the exact problem? Are you able to make GET request, but not the POST? Does the answer below work for you? Commented May 24, 2020 at 14:02
  • 1
    yes, that's my problem. And I didn't understand, what he below mean with 'event target key' expression Commented May 24, 2020 at 14:11

2 Answers 2

11

Here is what you can do:

Fetch games when component is mounted. And Submit new game when form is submitted.

export default function App() { const [data, setData] = useState([]) const [formData, setFormData] = useState('') useEffect(() => { fetchGames() // Fetch games when component is mounted }, []) const fetchGames = () => { fetch('http://localhost:3000/game', { method: 'GET', }) .then((res) => res.json()) .then((result) => setData(result.rows)) .catch((err) => console.log('error')) } const saveGames = () => { fetch('http://localhost:3000/game', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: formData, // Use your own property name / key }), }) .then((res) => res.json()) .then((result) => setData(result.rows)) .catch((err) => console.log('error')) } const handleSubmit = (event) => { event.preventDefault() saveGames() // Save games when form is submitted } const handleChange = (event) => { setFormData(event.target.value) } return ( <div className="App"> {/* method="post" not needed here because `fetch` is doing the POST not the `form` */} {/* Also, note I changed the function name, handleSubmit */} <form onSubmit={handleSubmit}> <input type="text" name="name" value={formData} onChange={handleChange} /> <button type="submit">click</button> </form> {data && data.map((element, index) => ( <GameTestResult name={element.name} key={element.index} /> ))} </div> ) } 

You can read this about how to use fetch and this about how forms work in RecatJS.

Sign up to request clarification or add additional context in comments.

2 Comments

Also, you should consider using axios instead of fetch. Axios works better on old browsers too. See this
Thank you. to be honest, I didn’t use it before, but will learn as well
4
  • Add name as "name" to input
  • Listen onChange and set data setFormData({[event.target.key]: event.target.value}) the data will be for example {name: "Tony"}
  • Call POST request on onClick action of button like code below
  • JSON.stringify(data) is important to convert js object to JSON when sending it to server
import GameTestResult from './GameTestResult' export default function App() { const [data, setData] = useState([]) const [formData, setFormData] = useState({}) useEffect(() => { fetch('http://localhost:3000/game') .then((res) => res.json()) .then((result) => setData(result.rows)) .catch((err) => console.log('error')) }, []) const handleChange = (event) => { setFormData({ [event.target.name]: event.target.value }) } const eventHandler = (event) => { fetch('http://localhost:3000/game', { method: 'POST', body: JSON.stringify(formData), }) .then((res) => res.json()) .then((result) => { console.log(result) setFormData('') }) .catch((err) => console.log('error')) } return ( <div className="App"> <form> <input name="name" value={formData.name || ''} onChange={handleChange} /> <button onClick={eventHandler}>click</button> </form> {data && data.map((element, index) => ( <GameTestResult name={element.name} key={element.index} /> ))} </div> ) } 

7 Comments

thanks for responding. I didn't understand only this part ---> setFormData({[event.target.key]: event.target.value}). Can you explain, please?
<input name="name" value = {formData} onChange = {handleChange} /> when handleOnchange is triggered you get an event, we will have event.target is an object which has properties of the input element. Fir this input, we have event.target.key is "name" and event.target.value is whatever string user typed. Then, {[event.target.key]: event.target.value} will become {name: "the string user type}. then you set it as formData
yes, I tried this way, but this doesn't allow me to type in input because now inside is '[object Object]' , when I try to type. and it sends empty rows to database
Sorry my bad, event.target.key should be event.target.name and <input name="name" value = {formData} onChange = {handleChange} /> should be <input name="name" value = {formData.name || "} onChange = {handleChange} />. {formData.name || "} mean if there is name property in formData` object show name if it undefined show empty. I updated my comment, please check it for updated info
@Gregfan. I am glad it helps. Please give it a vote if it really helps you.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.