Ivanka
Ivanka

Reputation: 248

Render results of two different queries at the same time in Node.js res.render

I am trying to show results of two SQL queries in one page. My code is in module.exports block and the whole application in written in Node.js Express. This returns an error "Cannot read property 'length' of undefined".

var message = "some random text";
var res_points, res_types;
    db.query(query, (err, result) => {
        if (err) {
            res.redirect('/');
        }
        res_points= result;
    });
    db.query(query2, (err, result) => {
        if(err) {
            res.redirect('/');
        }
        res_types = result;
    });

    res.render('index.ejs', {
        title: message,
        ,points: res_points
        ,types: res_types
    });

When I do it like this, it works:

db.query(query, (err, result) => {
        if (err) {
            res.redirect('/');
        }
        res.render('index.ejs', {
            title: message,
            points: result
        });
    });

What am I doing wrong? Or better said, how can I pass results of those two queries into the render function?

Upvotes: 0

Views: 1949

Answers (2)

Marcos Casagrande
Marcos Casagrande

Reputation: 40444

The cleanest approach here is to use Promises & Promise.all. For that you will need to wrap db.query in a Promise.

// You can use Util.promisify too
const queryWrapper = (statement) => {

    return new Promise((resolve, reject) => {

        db.query(statement, (err, result) => {
            if(err)
                return reject(err);

            resolve(result);
        });

    });

};


app.get('/some-route', (req, res, next) => {
    const message = "some random text";

    Promise.all([
        queryWrapper(query),
        queryWrapper(query2)
    ])
    .then(([points, types]) => {

        res.render('index.ejs', {
            title: message,
            points,
            types
        });
    })
    .catch(err => {
        console.error(err);
        res.redirect('/');
    })
});

Note: If you're using MySQL, the mysql2 package offers promise support, so you can avoid the Promise wrapper.

Upvotes: 1

Ivanka
Ivanka

Reputation: 248

I found a workaround like this, but I really don't think this is the only, corrent and elegant way how to do it:

    let res_points, res_types;
    db.query(query, (err, result) => {
        if (err) {
            res.redirect('/');
        }
        db.query(query2, (err2, result2) => {
            if(err2) {
                res.redirect('/');
            }
            res.render('index.ejs', {
                title: "Welcome to Hamburg Map | View Points"
                ,points: result
                ,types:result2
            });
        });
    });

Upvotes: 1

Related Questions