I am using trying to return a Postgres DB query via a GraphQL resolver. For some reason, result
is coming back as not defined when I (on purpose) query a row for an ID that doesn't exist. When I console log it, result
always comes back as expected:
result = {
rows: [],
...
}
However, when I run it and make a Query, or when I use node inspect index.js
and let it run until the debugger, it doesn't seem to recognize that result
is even defined. When I run console.log(result)
in Node when it hits the debugger, I get this error:
debug> console.log(result)
REPL2:1
console.log(result)
^
Uncaught ReferenceError: result is not defined
at REPL2:1:13
at Script.runInContext (node:vm:139:12)
at Object.runInContext (node:vm:289:6)
at REPLServer.controlEval (node:internal/debugger/inspect_repl:578:25)
at bound (node:domain:421:15)
at REPLServer.runBound [as eval] (node:domain:432:12)
at REPLServer.onLine (node:repl:898:10)
at REPLServer.emit (node:events:527:28)
at REPLServer.emit (node:domain:475:12)
at [_onLine] [as _onLine] (node:internal/readline/interface:424:12)
and when I run the query from the Playground, I get this error:
/Users/user/Projects/geolocatr_api/db/queries/user.queries.js:21
id: user.id,
^
TypeError: Cannot read properties of undefined (reading 'id')
at /Users/user/Projects/geolocatr_api/db/queries/user.queries.js:21:20
at Query.<anonymous> (/Users/user/Projects/geolocatr_api/node_modules/pg-pool/index.js:417:18)
at Query.handleReadyForQuery (/Users/user/Projects/geolocatr_api/node_modules/pg/lib/query.js:138:12)
at Client._handleReadyForQuery (/Users/user/Projects/geolocatr_api/node_modules/pg/lib/client.js:290:19)
at Connection.emit (node:events:527:28)
at /Users/user/Projects/geolocatr_api/node_modules/pg/lib/connection.js:114:12
at Parser.parse (/Users/user/Projects/geolocatr_api/node_modules/pg-protocol/dist/parser.js:40:17)
at Socket.<anonymous> (/Users/user/Projects/geolocatr_api/node_modules/pg-protocol/dist/index.js:11:42)
at Socket.emit (node:events:527:28)
at addChunk (node:internal/streams/readable:324:12)
Node.js v18.0.0
error Command failed with exit code 1.
I'm really not sure why my console logs seem to see that something is there, but Node doesn't. Otherwise, when an ID that exists in the table is passed in, it works as expected.
The code:
// Resolver
Query: {
user: ( _, { id } ) => {
console.log({id}); // Node recognizes this as the correct number
return getUserById(id);
},
},
// DB Query Function
const getUserById = (id) => {
return new Promise(function(resolve, reject) {
db.query(
`
SELECT id, first_name, email, phone
FROM users
WHERE id = $1;
`,
[id],
function(err, result) {
// debugger; // Result comes back as not defined
if (!result.rows) { // Will not run this if block
console.log(result.rows);
reject("Could not find user.");
}
if (err) reject(err);
const user = rows[0];
resolve({
id: user.id,
firstName: user.first_name,
email: user.email,
phone: user.phone,
});
}
);
});
};
CodePudding user response:
Typically with those (err, result) => { ... }
callbacks, you check err
first because if it is truthy, there's a good chance that the second argument will not be defined.
You should also return
after detecting an error to prevent the rest of your callback from executing.
FYI, node-postgresl supports promises natively so there's no need to explicitly create one. Below I've translated your code to an async function to take advantage of this.
const getUserById = async (id) => {
const { rows } = await db.query({
text: "SELECT id, first_name as firstName, email, phone FROM users WHERE id = $1",
values: [id],
});
// `rows` is always an array so check the length
if (rows.length !== 1) {
throw new Error(`Could not find user by id [${id}]`);
}
return rows[0];
};