I have a form that send a POST request to my backend server in node js to create an account in a database. The request returns a message if there was an error during the process and I want to put this message in my page.
When the process is done the page only display a json file with the message returned.
html form
<form action="/register" method='POST'>
<div>
<label for="username">username:</label>
<input type="text" name='username' placeholder='username'/>
</div>
<div>
<label for="email">email:</label>
<input type="text" name='email' placeholder='email'/>
</div>
<div>
<label for="password">password:</label>
<input type="text" name='password' placeholder='password'/>
</div>
<input type='submit' value="Submit" />
</form>
the node js request
app.post('/register', async (req, res) => {
const { username, email, password } = req.body;
let user = await userModel.findOne({email});
if (user) {
return res.status(403).send({ message: "This email already has an account" });
};
const hashed = await bcrypt.hash(password, 12);
user = new userModel({
username,
email,
password: hashed,
});
await user.save();
res.status(201).send({ message: "Account has ben created" });
});
My question is how can I get the response of the request easily to display it on the page?
You need to modify your approach as follows:
HTML Form (register.ejs)
<% if(locals.message) { %>
<div class="success-msg"><%= message %></div>
<% } %>
<% if(locals.error) { %>
<div class="error-msg"><%= error %></div>
<% } %>
<form action="/register" method='POST'>
<div>
<label for="username">username:</label>
<input type="text" name='username' placeholder='username'/>
</div>
<div>
<label for="email">email:</label>
<input type="text" name='email' placeholder='email'/>
</div>
<div>
<label for="password">password:</label>
<input type="text" name='password' placeholder='password'/>
</div>
<input type='submit' value="Submit" />
</form>
Node.js index
app.get('/register', async(req, res) => {
res.render('register');
});
app.post('/register', async(req, res) => {
const { username, email, password } = req.body;
let user = await userModel.findOne({email});
if (user) {
return res.render('register', {error: 'This email already has an account'});
};
const hashed = await bcrypt.hash(password, 12);
user = new userModel({
username,
email,
password: hashed,
});
await user.save();
return res.render('register', {message: 'Account has ben created'});
});
EDIT:- To implement this with react.js
Register.js
const dispatch = useDispatch();
const [userName, setUserName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [errorMsg, setErrorMsg] = useState('');
function submitForm(e){
e.preventDefault();
const bodyReq = {
username: userName,
email,
password
}
dispatch( registerRequest(bodyReq, onRegisterSuccess, onRegisterError) );
}
function onRegisterError(err){
setErrorMsg(err);
}
return (
<>
<div className="error-msg">{errorMsg}</div>
<form onSubmit={e => submitForm(e)} method='POST'>
<div>
<label htmlFor="username">username:</label>
<input value={userName} onChange={e => setUserName(e.target.value)} id="username" type="text" name='username' placeholder='username'/>
</div>
<div>
<label htmlFor="email">email:</label>
<input value={email} onChange={e => setEmail(e.target.value)} type="text" name='email' id='email' placeholder='email'/>
</div>
<div>
<label htmlFor="password">password:</label>
<input value={password} onChange={e => setPassword(e.target.value)} type="text" name='password' id='password' placeholder='password'/>
</div>
<input type='submit' value="Submit" />
</form>
</>
);
Server.js
app.post('/register', async (req, res) => {
const { username, email, password } = req.body;
let user = await userModel.findOne({email});
if (user) {
return res.status(403).json({ message: "This email already has an account" });
};
const hashed = await bcrypt.hash(password, 12);
user = new userModel({
username,
email,
password: hashed,
});
await user.save();
return res.status(201).json({ message: "Account has ben created" });
});