Search code examples
javascriptreactjsformsreact-bootstrap

How to loop through a subarray of input objects and access value - ReactJS, cannot type in input


I am working on this Form, which will allow to add multiple users and for each user is allowed add multiple goals. However each of these would be an input field. So far I have created the input field for users firstName and lastName and created a button to add more fields, however when I try to map through the goals I am not able to get the value from the goal array.

Here's the code for each section


//code for setting state
    const [users, setUsers] = useState([ { firstName: '', lastName: '' , goals: [{ mainGoal:'', subTasks:[] }]  }])//empty users array set when we start

Code for the form input


 <label className="boldLabel">Add Member</label>
                                {users.map((input, index) => { //initially we are mappin through the empty users array and creating one field in the return section
                                return (
                                    <div className="singleOwnerField" key={index}>
                                        <Row>                                                                  
                                            <Col>       
                                                <input
                                                    name='firstName'
                                                    placeholder='First Name'
                                                    value={input.firstName}
                                                    onChange={event =>handleAddMore(index,event)}
                                                />
                                            </Col>
                                            <Col>                                        
                                                <input
                                                name='lastName'
                                                placeholder='Last Name'
                                                value={input.lastName}
                                                onChange={event =>handleAddMore(index,event)}
                                            />
                                            </Col>
                                            <Col>
                                            {input.goals.map((goal,i)=>{
                                                return( 
                                                    <input key={i}
                                                    name='mainGoal'
                                                    placeholder='Main Goal Name'
                                                     value={goal.mainGoal}
                                                    onChange={event =>handleAddGoal(index,i,event)}
                                                />
                                                )
                                            })}

Then the function I use to add firstName and lastName to the user object (this works as expected)

    const handleAddMore = (index,event)=>{

        let data=[...users]
        data[index][event.target.name]=event.target.value
        setUsers(data) 
       
    }

Below is the function that is written to pick the input value from the goal input field

const handleAddGoal = (index,goalIndex,event)=>{

        let goalsOfUser=[...users[index].goals]
        goalsOfUser[goalIndex][event.target.name]=event.target.value

          console.log("printing goalsOfUser: " + JSON.stringify(goalsOfUser))
 
        console.log("users" + JSON.stringify(users))
        
       
    }

However when I access goal.mainGoal in the input field (a snippet from the form above) it doesn't show the value in the input field (ie. cant type in )

                                   <input key={i}
                                                    name='mainGoal'
                                                    placeholder='Main Goal Name'
                                                     value={goal.mainGoal}
                                                    onChange={event 
                                                            =>handleAddGoal(index,i,event)} />

I have tried console.logging in the handleAddGoal() function and it seems to print the user object with the first letter we type in the goal field but is not saved enter image description here

I have tried adding setUser(user) but still the same behevior

   const handleAddGoal = (index,goalIndex,event)=>{

        let goalsOfUser=[...users[index].goals]
        goalsOfUser[goalIndex][event.target.name]=event.target.value
 
        console.log("printing goalsOfUser: " + JSON.stringify(goalsOfUser))
    
        console.log("users" + JSON.stringify(users))
        setUsers(users)
  
    }

Solution

  • In handleAddGoal function you change the goal but you don't set the new data in users array.

    you need to do like this

    const handleAddGoal = (index,goalIndex,event)=>{
        let goalsOfUser=[...users[index].goals]
            goalsOfUser[goalIndex][event.target.name]=event.target.value
    
        const tempUsers = [...users]
        tempUsers[index].goals = goalsOfUser;
    
        setUsers(tempUsers)       
    }