Search code examples
htmlnode.jsforms

How to get the res of a form POST request in html?


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?


Solution

  • You need to modify your approach as follows:

    1. Render the form using a template engine (ejs, etc) from the same server.
    2. From the post request, rather than sending the json response, you can render the form template embedded with the success response or error messages (if any)

    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" });
    });