heliosk
heliosk

Reputation: 1161

Nodejs async/await mysql queries

I have a nodejs project with the current structure below, I need to insert a registry on clients table and return the last inserted ID from this table so I can use it in a second table, but I need to wait until the insert is completed in clients table, before insert the client ID on my second table. I'm trying to use async/await, but I'm always getting a null value.

My MYSQL connection: db.model.js

const config = require('config');
const mysql = require("mysql");

const connection = mysql.createConnection({
    host: config.get('mysql.host'),
    user: config.get('mysql.user'),
    password: config.get('mysql.password'),
    database: config.get('mysql.database')
});

connection.connect(function (err) {
    if (err) {
        console.error(`MySQL Connection Error: ${err.stack}`);
        return;
    }

    console.log(`MySQL connected successfully!`);
});

module.exports = connection;

My CLIENT model

const mysql = require("./db.model");

const Client = function(client) {
    this.login = client.login;
};

Client.create = (newClient, result) => {
    mysql.query("INSERT INTO clients SET ?", newClient, 
        (err, res) => {
            if (err) {
                console.log("error: ", err);
                result(err, null);
                return;
            }

            result(null, {
                id: res.insertId,
                ...newClient
            });
        }
    );
};

module.exports = Client;

this is the client controller (i'm trying to use async/await here)

const Client = require('../models/client.model');

exports.create = (login) => {
    const client = new Client({
        login: login
    });

    Client.create(client, async (err, data) => {
        if(!err) {
            return await data.id;
        } else {
            return false;
        }
    });
}

And this is another controller, where I want to use methods from my client controller:


const ClientController = require('../controllers/client.controller');

...

    utils.connect()
        .then(clt => clt.sub.create(data))
        .then((sub) => {

            let lastInsertedId = ClientController.create(sub.login);

            // lastInsertedId always return null here, 
            // but I know ClientController return a value after some time.
            // method below will fail because lastInsertedId cannot be null
            TransactionController.transactionCreate(lastInsertedId,
                                                    sub.id, 
                                                    sub.param);
        })
        .catch(error => res.send(error.response.errors))

any help appreciated.

Upvotes: 2

Views: 11805

Answers (3)

Rahul Patil
Rahul Patil

Reputation: 493

File to create database connection

const config = require('config');
const mysql = require('mysql2');
const bluebird = require('bluebird');

const dbConf = {
    host: config.dbhost,
    user: config.dbuser,
    password: config.dbpassword,
    database: config.database,
    Promise: bluebird
};

class Database {

    static async getDBConnection() {
        try {
            if (!this.db) {
                // to test if credentials are correct
                await mysql.createConnection(dbConf);
                const pool = mysql.createPool(dbConf);
                // now get a Promise wrapped instance of that pool
                const promisePool = pool.promise();
                this.db = promisePool;
            }
            return this.db;
        } catch (err) {
            console.log('Error in database connection');
            console.log(err.errro || err);
        }

    }
}

module.exports = Database;

Use connection to execute your native query

const database = require('./database');

let query = 'select * from users';
let conn = await dl.getDBConnection();
let [data, fields] = await conn.query(query);

Upvotes: 4

Devang Patel
Devang Patel

Reputation: 32

You can use sync-sql package of npm for execute async queries. https://www.npmjs.com/package/sync-sql

Here is an example of it:

const express = require('express')
const mysql = require('mysql')
const app = express()
var syncSql = require('sync-sql');
// Create Connection 
const connect = {
    host: 'localhost',
    user: 'root',
    password: '',
    database: 'ddd_test'
}
const db = mysql.createConnection(connect)
db.connect((err) => {
    if (err) {
        throw err
    }
    console.log("Connected");
})
function getDbData(query) {
    return syncSql.mysql(connect, query).data.rows
}
app.get("/getData", async (req, res, next) => {
    let sql = 'SELECT * from registration';

    res.json({
        data:getDbData(sql)
    });
})

app.listen(3000, () => {
    console.log('App listening on port 3000!');
});

Upvotes: 0

heliosk
heliosk

Reputation: 1161

So I'm still using only the npm mysql package, but now I transformed all my queries into promises like below, so I can just wait until all the queries are completed.

const create = (idCliente, transactionId, amount, status) => {

    const sql = "INSERT INTO transactions SET ?";
    const params = {
        id_cliente: idCliente,
        transaction_id: transactionId,
        amount: amount,
        status: status
    };

    return new Promise((resolve, reject) => {
        pool.query(sql, params, (err, result) => {
            if (err) {
                return reject(err);
            }
            resolve(result);
        });
    });
};

then I use like this:

create(params)
       .then((result) => { 
           //call more queries here if needed 
       })
       .catch((err) => { });

Upvotes: 3

Related Questions