I'm making a very simple authenticated website for learning giving users the ability to create an account log in and view content.
The issue is not seeing the registered users on the home page (as a test) after a successful post registration. After the post, I am redirecting the user back to the home page and the get route runs a postgres function using node-postgres module to retrieve all of the users in the database and returns them. That doesn't seem to be firing. Yet, when I run the same function in my database, I do see the new user.
What's weird is that when I hit enter on the home route in the browser afterwards, the new user does pop up. So I'm really not sure if this is a caching thing or not understanding promises correctly (I've just started getting into this) or something else.
I have tried using callbacks instead of promises as shown on here: https://node-postgres.com/features/queries to see if it makes a difference. Other than that, I've added log statements to see if the promise actually resolves or rejects. But it seems to always resolve so I'm really unsure what's going on here.
<!-- register.ejs -->
<%- include('partials/header') %>
<div class="container mt-5">
<h1>Register</h1>
<div class="row">
<div class="col-sm-8">
<div class="card">
<div class="card-body">
<!-- Makes POST request to /register route -->
<form action="/register" method="POST">
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" name="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-dark">Register</button>
</form>
</div>
</div>
</div>
</div>
</div>
<%- include('partials/header') %>
\\index.js (in ./db)
const {
Pool
} = require('pg');
const pool = new Pool({
database: 'secrets'
});
module.exports = {
query: (text, params, callback) => {
return pool.query(text, params, callback)
}
};
//jshint esversion:6
/* Imports
* ================================================================================ */
const express = require('express');
const bodyParser = require('body-parser');
const db = require('./db');
const util = require('util');
/* App setup
* ================================================================================ */
const app = express();
app.disable('etag');
const port = 3000;
app.use(express.static(util.format("%s/%s", __dirname, 'public')));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({
extended: true
}));
/* Routes
* ================================================================================ */
// Get request
app.get("/", function (req, res, next) {
db.query('SELECT * FROM dbo.usp_SelectUsers()')
.then(function(dbResult) {
console.log(dbResult.rows);
res.send(dbResult.rows);
}, (reason) => {
console.log("Not fulfilled :(");
}).catch(_err => next(_err));
});
// Post request for registration
app.post("/register", function (req, res, next) {
const queryText = 'SELECT dbo.usp_CreateUser($1, $2)';
const queryValues = [req.body.username, req.body.password];
db.query(queryText, queryValues)
.then(res.redirect("/"))
.catch(err => next(err))
});
CREATE OR REPLACE FUNCTION dbo.usp_SelectUsers()
RETURNS TABLE (User_ID INTEGER, User_Name VARCHAR(100)) AS
$func$
BEGIN
RETURN QUERY
SELECT u.User_ID
,u.User_Name
FROM dbo.User u
;
END
$func$ LANGUAGE plpgsql;
Expected result is to see new users in database and displayed on home page ("/") after successful post without having to refresh the page again.
I have updated my registration code to use async / await
as follows and this fixed everything for me. I realized that the issue I was having previously is that the post did not fully complete before the database call to retrieve the the list of users were made (ie: database did not yet have the new user when calling dbo.usp_SelectUsers
).
app.post("/register", async (req, res, next) => {
try {
const queryText = 'SELECT dbo.usp_CreateUser($1, $2)';
const queryValues = [req.body.username, req.body.password];
const results = await db.query(queryText, queryValues);
res.redirect("/login");
} catch (err) {
throw err;
}
});
As a side note, I have read that async / await is also much better to use nowadays and this fix added onto the pluses. Please see the following article for reference: https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9