I need to update users profile details, but my form only works when all input fields are filled, how do I only update those profile details, which are filled in the form.
My form has 4 fields updatable: Name, Email, Age, Password, and I am accepting them in this form :
<h1>Update profile details</h1>
<form action="" id="update-profile-form">
<input type="text" id="update-name" placeholder="New Name">
<input type="text" id="update-email" placeholder="New Email">
<input type="text" id="update-age" placeholder="New Age">
<input type="text" id="update-password" placeholder="New Password">
<button id="update-button">Update Filled</button>
<p id="update-details"></p>
</form>
My server-side JS code is :
const updateForm = document.querySelector( "#update-profile-form" );
updateForm.addEventListener( "submit", ( e ) => {
const name = document.querySelector( "#update-name" ).value;
const email = document.querySelector( "#update-email" ).value;
const age = document.querySelector( "#update-age" ).value;
const password = document.querySelector( "#update-password" ).value;
console.log( 'Profile update request' );
e.preventDefault();
fetch( "http://localhost:3000/users/me", {
method: 'PATCH',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json',
"Authorization": `Bearer ` + `${ inMemoryToken }`
},
body: JSON.stringify( {
"name": name,
"email": email,
"age": age,
"password": password
} )
} ).then( res => res.json() )
.then( res => {
console.log( res );
e.preventDefault();
document.querySelector( "#update-details" ).innerHTML = JSON.stringify( res );
}
);
} );
My backend NodeJS code is :
router.patch( "/users/me", auth, async ( req, res ) => {
const updates = Object.keys( req.body );
const allowedUpdates = [ "name", "email", "password", "age" ];
const isValidOperation = updates.every( ( update ) =>
allowedUpdates.includes( update )
);
if ( !isValidOperation ) {
return res.status( 400 ).send( { error: "Invalid updates" } );
}
try {
updates.forEach( ( update ) => ( req.user[ update ] = req.body[ update ] ) );
await req.user.save();
res.status( 201 ).send( req.user );
} catch ( e ) {
res.status( 404 ).send( {
e,
} );
}
} );
Any help will be highly appreciated. Please feel free to ask any questions about the question.
Put a console.log(updates)
just before the line updates.forEach( ( update ) => ( req.user[ update ] = req.body[ update ] ) );
in your backend code.
After checking what the values come in as on a partial form, you should be able to change it to something like:
updates.forEach(update => {
if (req.body[update] != "") {
req.user[update] = req.body[update]
}
});
So that it only applies the update if the request is not an empty string (depends what the default "empty" value is on your form).