sidorares / node-mysql2

:zap: fast mysqljs/mysql compatible mysql driver for node.js
https://sidorares.github.io/node-mysql2/
MIT License
4.08k stars 622 forks source link

Async/await not working? #782

Open aaronzolla opened 6 years ago

aaronzolla commented 6 years ago

I try this:

    let [one, two] = await connection.execute('SELECT EXISTS(SELECT 1 FROM bashbase.users WHERE email=?) AS "exists";', [req.body.email])

    console.log(one, two)

(node:19626) UnhandledPromiseRejectionWarning: TypeError: (intermediate value) is not iterable

when I try to add a .then, it says connection.execute.then is not a function

sidorares commented 6 years ago

hi @bash163 Can you show us how you get connection? Make sure it's coming from promise wrapper api

aaronzolla commented 6 years ago

Hi, thanks for responding so quickly.

Here is my code for db.js

import mysql from 'mysql2/promise';

export default mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: '...',
    database: 'bashbase'
});

I am then using it like this

connection.execute('SELECT EXISTS(SELECT 1 FROM bashbase.users WHERE email=?) AS "exists";', [req.body.email], async (emailError, emailResult) => {
                if (emailError || emailResult[0].exists === 1) {
                    connection.release();
                    res.status(500).send({ success: false, errorMessage: 'A user already exists with that email.' }).end();
                    next();
                    return;
                }
)}

Now this is how I've been using it up 'till now. I'd really like to get the promises actually working.

JiaJiaJiang commented 6 years ago

I use

var [cats]=await pool.execute(.....);
var [books]=await pool.execute(.....);

and gets TypeError: (intermediate value) is not iterable too.


update: I noticed that I should require('mysql2/promise') to get it to work.

sidorares commented 6 years ago

I wonder if there is any way we could detect incorrect await-ing of callback-style pool or connection. Maybe define .then on a returned Query object and when it's called by await throw some meaningful message?

aaronzolla commented 6 years ago

no idea

JiaJiaJiang commented 6 years ago

what about returning a Promise if no callback is provided?

sidorares commented 6 years ago

@bash163

change your code from

connection.execute('SELECT EXISTS(SELECT 1 FROM bashbase.users WHERE email=?) AS "exists";', [req.body.email], async (emailError, emailResult) => {
                if (emailError || emailResult[0].exists === 1) {
                    connection.release();
                    res.status(500).send({ success: false, errorMessage: 'A user already exists with that email.' }).end();
                    next();
                    return;
                }
)}

to


try {
  const [emailResult] = await connection.execute('SELECT EXISTS(SELECT 1 FROM bashbase.users WHERE email=? AS "exists"', [req.body.email]);
  connection.release();
} catch(e) {
  connection.release();
  res.status(500).send({ success: false, errorMessage: 'A user already exists with that email.' }).end();
  return next();
}
if ( emailResult[0].exists === 1) {
  res.status(500).send({ success: false, errorMessage: 'A user already exists with that email.' }).end();
}
sidorares commented 6 years ago

@JiaJiaJiang that's not compatible with current api and the whole reason "new" api exists separately Result of .query() is Query object

We might make Query object behave like a promise ( or maybe even derive it from promise ), not sure if it's good idea or not.

mdierolf commented 6 years ago

I added a .then() and .catch() function to Query which throws an error if they are used as if they are a promise, and a test-then-on-query.js unit test to confirm that behavior.

Over here: https://github.com/sidorares/node-mysql2/pull/811/commits/abab70e14d592db484e11a939b8241d0c1b324c6

sidorares commented 6 years ago

nice @mdierolf ! was going to mention this to you but you did anyway :)

Maybe instead of "Ooops. You have error here" also suggest how to solve it? Not sure what is best url to use, maybe https://www.npmjs.com/package/mysql2#using-promise-wrapper

Something like "If you want to use async/await or Promises check out documentation at https://www.npmjs.com/package/mysql2#using-promise-wrapper"

StefH commented 5 years ago

I had the same error when using Truffle to call a Ethereum Solitidy function like:

let [ one, two ] = await contract.execute(...);

I did change it to:

let x = await contract.execute(...);
// then just access one like x.one
JiaJiaJiang commented 5 years ago

@StefH Please try the solution here : https://github.com/sidorares/node-mysql2/issues/782#issuecomment-391451875

ashmilhussain commented 5 years ago

You have three options to write asynchronous code:

Using callbacks:

db.query( 'SELECT * FROM users WHERE id = 1', ( err, rows ) => {
  // ... use the result ...
} );

Using promises:

db.query( 'SELECT * FROM users WHERE id = 1' ).then( rows => {
  // ... use the result ...
} );

Using the await keyword:

const rows = await db.query( 'SELECT * FROM users WHERE id = 1' );

then you can use a try() catch() finally() for error handling

AdrianHastro commented 4 years ago

const mysql = require('mysql2/promise'); const conn = await mysql.createConnection({ database: bashbase }); const [rows, fields] = await conn.execute('SELECT EXISTS(SELECT 1 FROM bashbase.users WHERE email=?) AS "exists";', [req.body.email]); await conn.end();

singhrajkr commented 4 years ago

@AdrianHastro How you are using await without async function.

AdrianHastro commented 4 years ago

@SinghRajKr the code must be inside asyncfunction. i'm using .then() without asyncfunction

sidorares commented 4 years ago

@AdrianHastro I guess @SinghRajKr question was "is this example in top level scope? If yes, it won't work because node does not have top level await yet" - see https://stackoverflow.com/questions/46515764/how-can-i-use-async-await-at-the-top-level

singhrajkr commented 4 years ago

@sidorares I think top-level await a proposed feature for future JavaScript version.

@AdrianHastro Please update your comment. Otherwise, it may confuse newcomers who will visit to this issue.

Dotplaya commented 7 months ago

hi iam getting the same error for this code const [uniswapToken1, uniswapToken2] = await getReservesForUniswap(); const [quickswapToken1, quickswapToken2] = await getReservesForQuickSwap(); const [sushiswapToken1, sushiswapToken2] = await getReservesForSushiSwap();

here's the error: TypeError: (intermediate value) is not iterable at calculatePriceDifference (/root/MEVbot/Arbitrage/arbitrage.js:255:54) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async calculatePriceDifferenceForWETHUSDC (/root/MEVbot/Arbitrage/arbitrage.js:267:3) price of WETH-USDC pair in quickSwap 3.60255375706e-9 is there any other way to get around it?