I have a form field of a golf scorecard where the data is being placed into an array of objects for each golf hole. The nested teebox object for each hole is dynamic.
The issue: trying to maintain the previous teeBox[i] objects values. Only the last hole entered is kept.
I thought …teeBox[‘teeBox’ + tee] would preserve the previous values. I’ve tried many variations of this.
let scorecardData = []
let teeBox = {}
const handleScorecard = (e, hole, holeIndex, tee) => {
const { name, value } = e.target
if (name === 'tees') {
teeBox['teeBox' + tee] = {
...teeBox['teeBox' + tee],
'color': value
}
}
if (name === 'yards') {
teeBox['teeBox' + tee] = {
...teeBox['teeBox' + tee],
'yards': value
}
}
if (name === 'par') {
scorecardData[holeIndex] = {
...scorecardData[holeIndex],
'par': value,
}
}
if (name === 'handicap') {
scorecardData[holeIndex] = {
...scorecardData[holeIndex],
'handicap': value,
'Hole': hole
}
}
scorecardData[holeIndex] = {
...scorecardData[holeIndex],
tees: teeBox
}
}
<Table className={classes.scorecardTableContainer} aria-label="scorecard">
<TableBody>
<TableRow>
<TableCell className={classes.scorecardHolesCell}>Holes</TableCell>
{[1, 2, 3, 4, 5, 6, 7, 8, 9].map((x, i) => (
<TableCell className={classes.scorecardHolesCell} key={i}>
{x}
</TableCell>
))}
</TableRow>
{[1, 2, 3].map((tee, teeIndex) => (
<TableRow key={teeIndex}>
<TableCell>
<TextField
inputProps={{ maxLength: 10 }}
id={`teeBoxInput${tee}`}
name="tees"
placeholder={`Tee ${tee}`}
variant="outlined"
onChange={(e) => handleScorecard(e, 0, 0, tee)}
/>
</TableCell>
{[1, 2, 3, 4, 5, 6, 7, 8, 9].map((hole, holeIndex) => (
<TableCell key={holeIndex}>
<TextField
inputProps={{ maxLength: 3 }}
id={`yardInput${hole}`}
name="yards"
fullWidth
variant="outlined"
onChange={(e) => handleScorecard(e, hole, holeIndex, tee)}
/>
</TableCell>
))}
</TableRow>
))}
<TableRow>
<TableCell className={classes.scorecardParCell}>Par</TableCell>
{[1, 2, 3, 4, 5, 6, 7, 8, 9].map((hole, holeIndex) => (
<TableCell key={holeIndex}>
<TextField
inputProps={{ maxLength: 1 }}
id={`parInput${hole}`}
name="par"
fullWidth
variant="outlined"
onChange={(e) => handleScorecard(e, hole, holeIndex)}
/>
</TableCell>
))}
</TableRow>
<TableRow>
<TableCell className={classes.scorecardHandicapCell}>Handicap</TableCell>
{[1, 2, 3, 4, 5, 6, 7, 8, 9].map((hole, holeIndex) => (
<TableCell key={holeIndex}>
<TextField
inputProps={{ maxLength: 2 }}
id={`handicapInput${hole}`}
name="handicap"
fullWidth
variant="outlined"
onChange={(e) => handleScorecard(e, hole, holeIndex)}
/>
</TableCell>
))}
</TableRow>
</TableBody>
</Table>
What I’ve tried:
Setting the values in the array directly but using a dynamic key throws an error of (Parsing error: Unexpected token, expected ",")
scorecardData[holeIndex] = {
...scorecardData[holeIndex],
tees: {
teeBox['teeBox' + tee]: {
...teeBox['teeBox' + tee],
'color': value
}
}
}
Current output:
Hole 1 (first Object), does not maintain the first inputted yards of ‘444’ and ‘333’. Instead, both hole 1 and hole 2 have the second inputted yards of ‘321’ and ‘301’
[
{
"tees": {
"teeBox1": {
"color": "blue",
"yards": "321"
},
"teeBox2": {
"color": "white",
"yards": "301"
}
},
"par": "4",
"handicap": "1",
"Hole": 1
},
{
"tees": {
"teeBox1": {
"color": "blue",
"yards": "321"
},
"teeBox2": {
"color": "white",
"yards": "301"
}
},
"par": "4",
"handicap": "2",
"Hole": 2
}
]
Expected output:
Hole 1 (first Object), maintains the first inputted yards of ‘444’ and ‘333’
[
{
"tees": {
"teeBox1": {
"color": "blue",
"yards": "444"
},
"teeBox2": {
"color": "white",
"yards": "333"
}
},
"par": "4",
"handicap": "1",
"Hole": 1
},
{
"tees": {
"teeBox1": {
"color": "blue",
"yards": "321"
},
"teeBox2": {
"color": "white",
"yards": "301"
}
},
"par": "4",
"handicap": "2",
"Hole": 2
}
]
2
Answers
You are re-using the same object reference
teeBox
:Effectively,
scorecardData[0].tees
andscorecardData[1].tees
are pointing to the same objectteeBox
of which you are manipulating values.You need to create a new (independant) object.
Copy the entire
teesBox
object withstructuredClone
so that you aren’t reusing the same reference every time.