I want to return data coming from db to the api. The data is being logged but not showing on the graphql api.
const express = require('express'); const bodyParser = require('body-parser'); const graphqlHttp = require('express-graphql'); const { buildSchema } = require('graphql'); var mysql = require('mysql'); const app = express(); //start mysql connection var connection = mysql.createConnection({ host : 'localhost', //mysql database host name user : 'root', //mysql database user name password : '', //mysql database password database : 'test' //mysql database name }); connection.connect(function(err) { if (err) throw err }) //end mysql connection app.use(bodyParser.json()); app.use( '/graphql', graphqlHttp({ schema: buildSchema(` type users { id: String! username: String! password: String! role: String! name: String! photo: String! } type RootQuery { getUsers: [users!]! } type RootMutation { createUsers(name: String): String } schema { query: RootQuery mutation: RootMutation } `), rootValue: { getUsers: () => { connection.query('select * from users', function (error, results, fields) { if (error) throw error; console.log(JSON.stringify(results)) return JSON.stringify(results) ; }); }, createUsers: (args) => { const eventName = args.name; return eventName; } }, graphiql: true }) ); app.listen(3000);
RESULT:
query { getUsers { id } }
OUTPUT:
{ "errors": [ { "message": "Cannot return null for non-nullable field RootQuery.getUsers.", "locations": [ { "line": 3, "column": 3 } ], "path": [ "getUsers" ] } ], "data": null }
Advertisement
Answer
This is your resolver:
getUsers: () => { connection.query('select * from users', function (error, results, fields) { if (error) throw error; //users = results; console.log(JSON.stringify(results)); return JSON.stringify(results) ; }); },
A GraphQL resolver must return either a value or a Promise that will resolve to a value. However, here, you’re not returning either. Keep in mind that callbacks are invoked asynchronously, so returning a value inside a callback does nothing (in most cases).
You really should use something like promise-mysql
instead of mysql
, but you can still wrap a callback with a Promise and return that Promise. Something like this should work:
getUsers: () => { // Note, we have to return the Promise here return new Promise((resolve, reject) => { connection.query('select * from users', (error, results, fields) => { if (error) { reject(error) } else { // Don't stringify resolve(results) } }) }) },