Home > Blockchain >  NodeJS "synchronous" function call returns [object Promise]
NodeJS "synchronous" function call returns [object Promise]

Time:10-01

I wanted to create a platform to learn the power of NodeJS, so I arranged a web application that uses SQLite. I wanted to make the web app show a random post, so I made the web app select one:

var post = db.run("SELECT post_name FROM posts ORDER BY RANDOM() LIMIT 3;")

When I try to use post to get the entire row that it's results are included in:

var postrow = db.all("SELECT * FROM posts WHERE post_name = ${post}") // return object promise

As you can see, it will return [object Promise], causing a database error since there is no column named like that. But this really confuses me because the column is post_name, post is supposed to be the value, not the column. I have tried a lot (if not all) of the methods I could find, and it still would return [object Promise] no matter what. I am using NodeJS v18.2. My full code is:

app.get("/home", function(req,res){
 var post1 = db.run("SELECT post_name FROM posts ORDER BY RANDOM() LIMIT 3;").then(function(value) {
  return value;
 });
 res.render(__dirname   "/public/index.html", {
  post1: post1,
  postowned: db.run(`SELECT ownedby FROM posts WHERE post_name = ${post1}`)
 })})

Edit: The definition of db is:

dbWrapper
.open({
 filename: dbFile,
 driver: sqlite3.Database
})
.then(async dBase => {
db = dBase;

try {
  if (!exists) {
    await db.run(
      "CREATE TABLE posts ( post_name VARCHAR(20), post_text TEXT, ownedby VARCHAR(15), cdate TIMESTAMP );"
    );
  }
  console.log(await db.all("SELECT post_name from post"));
} catch (dbError) {
  console.error(dbError);
} });

CodePudding user response:

db.run and db.all are both asynchronous functions, so they will return [object Promise]. Nonetheless, it is possible to change the value to the actual response by using db.runs optional callback parameter, The code below selects a random post:

var posts = []
db.run("SELECT * FROM posts ORDER BY RANDOM() LIMIT 3;", function(err, row) {
 if (row.post_name != null){ 
  // if the post name is not null then push it to posts
  posts.push({ title:row.post_name, text:row.post_text, date:row.cdate, owned:row.ownedby})
 }
})
// the columns will be available in posts as 0, 1, it goes on as more posts are selected

It is possible to only select columns that you want by using the comma (for instance SELECT post_name, post_text FROM posts)

Since app.get is a synchronous function, and you can't call it with async, this does not use await, but this would still work as it won't give the promise response.

  • Related