'How can I pass in an unknown amount of objects in a dynamic react form to my sql database?
I'm having trouble connecting 0-6 dynamically rendered form elements to the backend/database using react. Perhaps the way I'm attempting to do this is not supported? Any advice would be really appreciated.
Index.js file in "backend" directory:
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const mysql = require('mysql');
//const { restart } = require('nodemon');
const app = express();
app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.json());
app.listen('3001', () => {
console.log("Running on port 3001.");
});
const db = mysql.createPool ({
host: '[redacted]',
user: '[redacted]',
password: '[redacted]',
database: '[redacted]'
});
app.get('/', function(req, res){
res.send("backend");
});
app.post('/', function (req, res) {
db.getConnection(function (err, db) {
const lastName = req.body.lastName;
const firstName = req.body.firstName;
const address = req.body.address;
const street = req.body.street;
const apartment = req.body.apartment;
const city = req.body.city;
const zipcode = req.body.zipcode;
const phone = req.body.phone;
const dateOfArrival = req.body.dateOfArrival;
const dateReceived = req.body.dateReceived;
const countryOfOrigin = req.body.countryOfOrigin;
const immigrationStatus = req.body.immigrationStatus;
const speaksEnglish = req.body.speaksEnglish;
const notes = req.body.notes;
const childField = req.body.childField; //and array of information about the children
const sqlInsertParent = "INSERT INTO Parent (parent_id, lastName, firstName, address, street, apartment, city, zipcode, "
+ "phone, dateOfArrival, dateReceived, countryOfOrigin, immigrationStatus, speaksEnglish, notes) VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
const sqlInsertChild = "INSERT INTO Children (child_id, parent_id, childFirstName, gender, age, shoe, childNotes) VALUES (?, ?, ?, ?, ?, ?, ?)";
//insert the parent into the database
db.query(sqlInsertParent, ["", lastName, firstName, address, street, apartment,
city, zipcode, phone, dateOfArrival, dateReceived,
countryOfOrigin, immigrationStatus, speaksEnglish, notes], (err, result) => {
console.log(err);
});
//Get the max parent_id from the Parent table (this will go into the Children table)
db.query('SELECT max(parent_id) FROM Parent', function (error, results, fields) {
/*NOTE: The Parent table will never be null because even if it's empty at first, the insert
into the parent table comes before the insert into the child table.*/
if (error) {
throw error;
}
//Convert the result into a number:
var s = JSON.stringify(results);
var json = JSON.parse(s);
var obj = json[0];
objVal = Object.values(obj);
var maxParentID = Number(objVal);
//Insert the children into the database
//https://stackoverflow.com/questions/51193704/react-input-setstate-for-array-of-objects
// for(let i = 0; i < childField.length; i++) {
// db.query(sqlInsertChild, ["", maxParentID,childField[i].childFirstName, childField[i].gender, childField[i].age,
// childField[i].shoe, childField[i].childNotes], (err, result) => {
// console.log(err);
// });
// }
});
});
});
help.js in "frontend" directory -- this is where the form is:
import Sponsors from "./Sponsors";
import ChildForm from "./ChildForm";
import React, { useState } from "react";
import axios from 'axios'; //allows us to create api requests
// this component renders the request help page
const Help = () => {
const [sample, sampleSet] = useState(null);
console.log(sample);
const addChild = (e) => {
var children = []
switch (e.target.value) {
case '0' : setChildrenState(null);
case '1' :
setChildrenState(
<ChildForm childTitle={'Child 1'} sampleSet={sampleSet}/>
)
break;
case '2' :
setChildrenState(
<>
<ChildForm childTitle={'Child 1'}/>
<ChildForm childTitle={'Child 2'}/>
</>
)
break;
case '3' :
setChildrenState(
<>
<ChildForm childTitle={'Child 1'}/>
<ChildForm childTitle={'Child 2'}/>
<ChildForm childTitle={'Child 3'}/>
</>
)
break;
case '4' :
setChildrenState(
<>
<ChildForm childTitle={'Child 1'}/>
<ChildForm childTitle={'Child 2'}/>
<ChildForm childTitle={'Child 3'}/>
<ChildForm childTitle={'Child 4'}/>
</>
)
break;
case '5' :
setChildrenState(
<>
<ChildForm childTitle={'Child 1'}/>
<ChildForm childTitle={'Child 2'}/>
<ChildForm childTitle={'Child 3'}/>
<ChildForm childTitle={'Child 4'}/>
<ChildForm childTitle={'Child 5'}/>
</>
)
break;
case '6' :
setChildrenState(
<>
<ChildForm childTitle={'Child 1'}/>
<ChildForm childTitle={'Child 2'}/>
<ChildForm childTitle={'Child 3'}/>
<ChildForm childTitle={'Child 4'}/>
<ChildForm childTitle={'Child 5'}/>
<ChildForm childTitle={'Child 6'}/>
</>
)
break;
default:
//no default because the user can only select 1-> 6
}
}
const [lastName, setLastName] = useState('');
const [firstName, setFirstName] = useState('');
const [address, setAddress] = useState('');
const [street, setStreet] = useState('');
const [apartment, setApartment] = useState('');
const [city, setCity] = useState('');
const [zipcode, setZipcode] = useState('');
const [phone, setPhone] = useState('');
const [dateOfArrival, setDateOfArrival] = useState(null);
const [dateReceived, setDateReceived] = useState(null);
const [countryOfOrigin, setCountryOfOrigin] = useState('');
const [immigrationStatus, setImmigrationStatus] = useState(null);
const [speaksEnglish, setSpeaksEnglish] = useState(null);
const [notes, setNotes] = useState('');
//const [childField, setChildrenState] = useState(null);
const submitHelpForm = () => {
console.log(childField);
axios.post('http://localhost:3001/', {lastName: lastName, firstName: firstName, address: address,
street: street, apartment: apartment, city: city,
zipcode: zipcode, phone: phone, dateOfArrival: dateOfArrival,
dateReceived: dateReceived, countryOfOrigin: countryOfOrigin,
immigrationStatus: immigrationStatus, speaksEnglish: speaksEnglish, notes: notes,
/*childField: childField*/
}).then(() => {
alert('successful insert');
});
};
return (
<div className="help-request-container">
<h3 className="request-header">
If you are a newcomer and your children need basic necessities, please complete the form below.
We will contact you soon with more information about becoming a Starting Point family.
</h3>
<form className="request-help-form" /*onSubmit={submitHelpForm} */>
<input type={'text'} placeholder='Parent Last Name' maxlength='250' required onChange={(e) => {setLastName(e.target.value)}}/>
<input type={'text'} placeholder='Parent First Name' maxlength='250' required onChange={(e) => {setFirstName(e.target.value)}}/>
<input type={'text'} placeholder='Street Number - example: 2311' maxlength='10' required onChange={(e) => {setAddress(e.target.value)}}/>
<input type={'text'} placeholder='Street Name - example: Hamlet Way' maxlength='250' required onChange={(e) => {setStreet(e.target.value)}}/>
<input type={'text'} placeholder='Apt/Suite/Unit/Building/Floor - example: Apt. 4' maxlength='20' onChange={(e) => {setApartment(e.target.value)}}/>
<input type={'text'} placeholder='City - example: Manhattan' maxlength='25' required onChange={(e) => {setCity(e.target.value)}}/>
<input type={'text'} placeholder='Postal Code - example: 80456' maxlength='15' required onChange={(e) => {setZipcode(e.target.value)}}/>
<input type={'text'} placeholder="Phone Number" required onChange={(e) => {setPhone(e.target.value)}}/>
<label for="date">Input Date arrived in US:</label>
<input type={'date'} placeholder='Date arrived in US' required onChange={(e) => {setDateOfArrival(e.target.value)}}/>
<label for="date">Input Current Date:</label>
<input type={'date'} placeholder='Current Date' required onChange={(e) => {setDateReceived(e.target.value)}}/>
<input type={'text'} placeholder='Country of Origin - example: Afghanistan' maxlength='250' required onChange={(e) => {setCountryOfOrigin(e.target.value)}}/>
<label for="Immigration Status">Select an Immigration Status:</label>
<select id="immigration status" name="immigrationStatus" onChange={(e) => {setImmigrationStatus(e.target.value)}}>
<option value="Other">Other</option>
<option value="SIV">SIV</option>
<option value="Evacuee">Evacuee</option>
<option value="Parolee">Parolee</option>
<option value="Asylee">Asylee</option>
<option value="Diversity Visa Holder">Diversity Visa Holder</option>
</select>
<label for="language">Do you speak English?</label>
<select id="language" name="language" onChange={(e) => {setSpeaksEnglish(e.target.value)}}>
<option value="No">No</option>
<option value="Yes">Yes</option>
</select>
<input type={"text"} placeholder='Notes About Parent' maxlength='250' onChange={(e) => {setNotes(e.target.value)}}/>
<label for="children">How many children do you have?</label>
<select id="children" name="children" onChange={addChild}>
<option value={0}>No Response</option>
<option value={1}>1</option>
<option value={2}>2</option>
<option value={3}>3</option>
<option value={4}>4</option>
<option value={5}>5</option>
<option value={6}>6</option>
</select>
<div className="child-add-form">
{childField}
</div>
<input type="submit" value="Submit" onClick={submitHelpForm}></input>
</form>
{/*{ console.log(child) }*/}
{/* render sponsors component at bottom of page. */}
<Sponsors />
</div>
)
}
export default Help
Solution 1:[1]
Your request to the server has to have the children in an array. Your coding style seems to bring forth a beginner level, so I would suggest adding one state item per child (6 total) and constructing an array based on how many children have been added.
This can be done relatively easily with a couple of changes: use a state item to hold the selected amount, and use props to update individual children states
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | gear4 |

