简体   繁体   中英

using .then nodejs

I have a large function that says, okay add this employee to the db based on what the admin entered. But now I need to check, does this user already exist in the db. so I created a function that does just that called getEmployeeNum , but I need to perform a.then in the main function of /addEmployee to say, see what the result of the function getEmployeeNum is before you perform any of the other requests. see the code below:

app.post('/addEmployee', (req, res) => {
    if (req.session.loggedin) {
        var firstname = req.body.firstname;
        var lastname = req.body.lastname;
        var username = req.body.username;
        var sales = req.body.sales;
        var salary = req.body.salary;
        var location = req.body.location;
        var role = req.body.role;
        var admin = req.body.admin;
        var employeenum = req.body.employee_num;
        var phonenum = req.body.phone_num;
        var org = req.body.org;
        var pass = "";
        var newPassword = req.body.password

        getEmployeeNum(req, res, employeenum)
        bcrypt.hash(newPassword, saltRounds, function(err, hash) {
            pass = hash
            addLogin(req, res, pass, firstname, lastname, username, sales, salary, location, role, admin, employeenum, phonenum)
        });

        var addEmployee = "insert into EMPLOYEES (FIRSTNAME, LASTNAME, USERNAME, SALES, SALARY, LOCATION, ROLE, ADMIN, EMPLOYEE_NUM, PHONENUM, ORGANIZATION) VALUES ('" +
            req.body.firstname +
            "', '" +
            req.body.lastname +
            "', '" +
            req.body.username +
            "', '" +
            req.body.sales +
            "', '" +
            req.body.salary +
            "', '" +
            req.body.location +
            "', '" +
            req.body.role +
            "', '" +
            req.body.admin +
            "', '" +
            req.body.employee_num +
            "', '" +
            phonenum +
            "', '" +
            org +
            "' )";
        ibmdb.open(ibmdbconnMaster, function(err, conn) {
            if (err) return console.log(err);
            conn.query(addEmployee, function(err, rows) {
                if (err) {
                    console.log(err);
                }
                registerEmail(username, firstname, lastname, req, res)
                res.redirect('/employees')
            })
        })
    } else {
        res.render('login.ejs')
    }
})





function getEmployeeNum(req, res, employeenum) {
    var getEmployeeNum = "select * from employees"
    ibmdb.open(ibmdbconnMaster, function(err, conn) {
        if (err) return console.log(err);
        conn.query(getEmployeeNum, function(err, rows) {
            if (err) {
                console.log(err);
            }

            for (var i = 0; i < rows.length; i++) {
                var employee_num = rows[i]["EMPLOYEE_NUM"]
                if (employeenum == employee_num) {
                    alert("employee already exists")
                    res.render("addEmployee.ejs")
                }
            }

            conn.close(function() {
                // console.log("closed the function /index");
            });
        });
    })
}

is this the right way to do it, or is there a better way? Thanks:)

I see that you're using the callback version of SQL driver. I'll assume that you;re working with mysql2 for simplicity wise.

There is actually a promise version of mysql2 driver

const mysql = require('mysql2/promise');

I'll share with you some of the common patterns I use when working with DB.

// Create a pool for connection 
const pool = mysql.createPool({
  connectionLimit: process.env.SQL_CON_LIMIT,
  host: process.env.SQL_SERVER,
  port: process.env.SQL_PORT,
  user: process.env.SQL_USERNAME,
  password: process.env.SQL_PASSWORD,
  database: process.env.SQL_SCHEME,
  timezone: process.env.SQL_TIMEZONE,
});

// To use async to test the connection via conn.ping() before launch server
  const p1 = (async () => {
  const conn = await pool.getConnection();
  await conn.ping();
  conn.release();
  return true;
})();

// test connection for SQL, add other into array as you like
Promise.all([p1]) 
  .then(() => {
    app.listen(PORT, () =>
      console.info(
        `Application started on port http://localhost:${PORT}/ at ${new Date()}`
      )
    );
  })
  .catch((err) => {
    console.error('Cannot connect: ', err);
  });

The code block above is for setting up, and test connection before starting the server. This can avoid the rare case where DB is not initialized before the request came in (As the server can start before connecting to DB)

const makeQuery = (query, pool) => {
  return async (args) => {
    const conn = await pool.getConnection();
    try {
      let results = await conn.query(query, args || []);
      return results[0]; // Result of query is in index 0
    } catch (error) {
      console.log(error);
    } finally {
      conn.release();
    }
  };
};

    // Sample query
    const queryCheckLogin =
      'SELECT COUNT(*) as "match" FROM user WHERE user_id = ? AND password = ?';
    // Make it into function!
    const checkLogin = makeQuery(queryCheckLogin, pool);
    
    app.post('/api/login', async (req, res) => {
      let { user_id, password } = req.body;
      // Obtain sha1 password from submitted password
      password = sha1(password);
      try {
        let results = await checkLogin([user_id, password]);
        // Return the credential (supposedly token) when record is matched
        if (results[0]['match'] !== 0) {
          res.status(200).json({ login: 'success', user_id, password });
        } else {
          // return 401 if record not found
          res.status(401).json({ error: 'No such username or password' });
        }
      } catch (error) {
        console.log(error);
        res.status(400).json(error);
      }
    });

The code block above shows the factory function to deal with the general form of getting the result from a query, so you won't clutter the logic in middleware. So you will write out whatever query you will do, make it into function via makeQuery , and just use the resulting function.

Using async...await will also make the code cleaner, however, this depends on the version of codebase you're working on. However, the sample above do works for .then as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM