skip to Main Content

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


  1. You are re-using the same object reference teeBox:

    let teeBox = {}
    
    ...
    
    scorecardData[holeIndex] = {
        ...scorecardData[holeIndex],
        tees: teeBox
    }
    

    Effectively, scorecardData[0].tees and scorecardData[1].tees are pointing to the same object teeBox of which you are manipulating values.

    You need to create a new (independant) object.

    Login or Signup to reply.
  2. Copy the entire teesBox object with structuredClone so that you aren’t reusing the same reference every time.

    scorecardData[holeIndex] = {
        ...scorecardData[holeIndex],
        tees: structuredClone(teeBox)
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search