I am writing middleware to return database queries using SQLite3 and Next.js. Here is a snippet of code that I wrote to return the contents of a DB table. It appears to work, and my checks of sources appear solid, with mixed reviews about the use of bind().
// route = /dbread
import { NextResponse } from 'next/server';
const sqlite3 = require("sqlite3").verbose();
const util = require('util');
export async function GET(req) {
const db = new sqlite3.Database("./database.db");
const dbAll = util.promisify(db.all).bind(db);
let response = await dbAll('SELECT * FROM "text"')
.then(db.close())
.catch((err => {
console.log(err);
return ['error'];
}));
return NextResponse.json(JSON.stringify(response));
}
However, if I take bind out, it breaks, so I keep that in, even though I don't fully understand what it's doing. Is there a better way to do this? The solution seems simple enough, but I just want to make sure I'm stepping on solid ground.
What you have with
.bind(db)works fine and is a correct way of doing things.I prefer to keep the same type of calling convention that other methods have by doing it like this:
And, then you call it like this:
like you would call any other method on the database, but that's just my personal preference. Either way will work. Calling this way also "binds" the
dbinstance to the method call so it's properly available asthisin the method for the method to use in its implementation.By way of explanation. When you call a method as in:
That makes the
objvalue available asthisin the method's implementation. For your db implementation that is needed.When you do this:
dbAll()has become a regular function call and the value ofthisis either the global object (in non-strict mode) orundefined(if running in strict mode). And, thus the implementation ofdbAll()does not have any access to thedbvariable which would make it not work. It expectsdbto be inthis. Adding.bind()the way you did forces the value ofthisto be set todb. But, method calls as inobj.method()ordb.allP()do this automatically for you. That's whydb.allP()doesn't need.bind()to work properly.FYI, you may want to just use a sql module that has an interface that already supports promises rather than manually promisifying individual methods upon demand.