0

I have my index.js like this

var express = require('express');
var app = express();

var list = require('./data').list;

// [...] 

app.get('/', function (req, res) {
  res.render('home',{
      list: list,
    });
});

and data.js that should ask the database server for data

const { Pool, Client } = require('pg')

var list = [];

const pool = new Pool({
  connectionString: '...',
})
pool.query('select * from list', (err, res) => {
  if(res){
    list = res.rows;
  }
  pool.end()
})

exports.list = list;

The problem is that when the page is rendered the list is empty and the database call happens after the page render. Is there a way to avoid this?

1
  • There is no guarentee that list will be available when the request to / is made. First make sure your query has finished executing before the request is made. Commented May 22, 2020 at 14:37

2 Answers 2

2

pool.query is an asyncronous function. You can solve your issue in many different ways, i would convert your db logic to a function that returns a promise. Then turn your HTTP handler into an async handler, and await the "promise of data" from "data.js". Like this:

// index.js
const express = require('express');
const app = express();

const { getList } = require('./data');

app.get('/', async (req, res) => {

  res.render('home', {
    list: await getList(),
  });
});
// data.js
const { Pool } = require('pg');

exports.getList = () => new Promise((resolve) => {
  const pool = new Pool({
    connectionString: '...',
  });
  pool.query('select * from list', (err, res) => {
    if (res) {
      resolve(res.rows);
    }
    pool.end();
  });
});
Sign up to request clarification or add additional context in comments.

Comments

-1

You could separate into controllers those files like:

first create a controller and exporting the functions for example your data.js:

exports.ListFunction= async function (req, res, next) {
var list = [];

const pool = new Pool({
  connectionString: '...',
})
await pool.query('select * from list', (err, res) => {
  if(res){
    list = res.rows;
//here i save the list variable so it can be used in other files
    req.list= list;
//next() call the next function.

  }
  pool.end();
next();
})
}

Then create a controller to render the page and pass the req.list variable as a parameter

exports.RenderHome = function(req, res){
res.render('home',{
      list: req.list,
    });

}

finally in your index.js

//import your controllers
var list= require('./listController')
var home= require('./renderHome')
//call each function from the controllers
app.get('/', list.ListFunction, home.RenderHome);

I think this is the best way to manage data before sending it to the client.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.