2

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.

1
  • You can use 'mysql2' to use promisified methods. Commented Mar 6, 2020 at 18:45

3 Answers 3

4

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);
Sign up to request clarification or add additional context in comments.

2 Comments

You probably shouldn't catch that error. This only causes conn to become undefined and will provoke just another exception with a worse error message.
@Bergi, it's up to you. This is just sample code I shared either you can just log or you can handle and throw it again.
3

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) => { });

Comments

0

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!');
});

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.