0

I am new to React, and I am currently working on an app using the MERN stack and was looking for a bit of advice.

I have React User component that calls & renders a user object with embedded documents from mongodb. When I return the data from the database, it does so in the following format:

{
  firstName: "joe",
  lastName: "smith",
  address: [
      {
        street: "123 Street",
        city: "UpCity",
      },
   ],
};

I have set the address up as an embedded document/array of addresses in mongo, and need to keep this format.

On my user component, I am displaying the returned values text controls, which I want the user to be able to edit, update and submit back to the DB. I have been successful in getting the object data to update, but editing the array, within the object has left me stumped for days now. Ideally wanted to pass the user object back in the same format so I didn't have to deconstruct the "req.body" and map this to the corresponding fields - unless this is the only way this can be done.

I have no issue with updating the state of the "user" fields but can't seem to figure out how to update the state of the address data, held in the embedded array. Below is an excerpt of my code

  const [data, setData] = useState({
    firstName: "",
    lastName: "",
    address: [
      {
        street: "",
        city: "",
      },
    ],
  });

  const onChange = (e) => {
    setData({
      ...data,
      [e.target.name]: e.target.value,
    });
  };

return ( 
         <div> 
                        <TextField
                          type="text"
                          name="firstName"
                          value={data.firstName}
                          onChange={onChange}
                        />
                        <TextField
                          type="text"
                          name="lastName"
                          value={data.lastName}
                          onChange={onChange}
                        />
                      </div>
                       <TextField
                        type="text"
                        name="street"
                        value={data.address[0].street}
                        onChange={onChange}
                      />
                      <TextField
                        type="text"
                        name="city"
                        value={data.address[0].city}
                        onChange={onChange}
                      />
)

Would you have any advice?

Should I simply manage the data as a simple object and map the embedding to an array, before submitting it to the DB, or am I missing something really simple?

note: I'm using mongoose & axios also

McGooks
  • 31
  • 5
  • your address can be multiple as they are In an array, but in code there are only 2 inputs – Arfan ali Mar 10 '21 at 14:22
  • that's correct, as it will be an array of objects. Over time the expectation is that this will be populated with more address – McGooks Mar 10 '21 at 14:26

1 Answers1

1

here is the simplest solution

    const onChange = (e, type=false) => {
    if(type){
        data.address[0][e.target.name] = e.target.value
        setData({...data})
    }else{
        setData({
            ...data,
            [e.target.name]: e.target.value,
        });
    }
};

return (
    <div>
        <TextField
            type="text"
            name="firstName"
            value={data.firstName}
            onChange={(e)=>onChange(e)}
        />
        <TextField
            type="text"
            name="lastName"
            value={data.lastName}
            onChange={(e)=>onChange(e)}
        />

        <TextField
            type="text"
            name="street"
            value={data.address[0].street}
            onChange={(e)=>onChange(e, true)}
        />
        <TextField
            type="text"
            name="city"
            value={data.address[0].city}
            onChange={(e)=>onChange(e, true)}
        />
    </div>
)
Arfan ali
  • 429
  • 2
  • 5