Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I call an asynchronous node.js function from within a GraphQL resolver requiring a return statement?

The Hello World example provided on graphql.org/graphql-js for creating a simple GraphQL implementation is the following:

var { graphql, buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
    type Query {
        hello: String
    }
`);

// The root provides a resolver function for each API endpoint
var root = {
    hello: () => {
        return 'Hello World!';
    }
};

// Run the GraphQL query '{ hello }' and print out the response
graphql(schema, '{ hello }', root).then((response) => {
    console.log(response);
});

I'm trying to run an asynchronous function within the resolver, for example a database call, and I can't seem to figure out how to make that work:

What I'm trying to do:

var { graphql, buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
    type Query {
        data: String
    }
`);

// The root provides a resolver function for each API endpoint
var root = {
    data: () => {
        getData((data) => {
            return data;    // Returns from callback, instead of from resolver
        }
    }
};

// Run the GraphQL query '{ data }' and print out the response
graphql(schema, '{ data }', root).then((response) => {
    console.log(response);
});

I've tried to use promises, but there doesn't seem to be a way of escaping the promises without entering a callback. I've also tried various ways of wrapping the asynchronous getData function to force it to be synchronous, but end up having to return a value from an asynchronous function, same problem. I feel like this can't be this complicated, I mean GraphQL-JS was written by Facebook.

like image 526
TheEnvironmentalist Avatar asked May 12 '17 05:05

TheEnvironmentalist


People also ask

How to write an asynchronous function in Node JS?

The asynchronous function can be written in Node.js using ‘async’ preceding the function name. The asynchronous function returns implicit Promise as a result.

How does the function asynchronouscall work?

Note how the function asynchronousCall is void. It returns nothing. Instead, by calling asynchronousCall with an anonymous callback function ( asynchronousCall (function (result) {... ), this function executes the desired actions on the result, but only after the request has completed – when the responseText is available.

What is the use of async function in JavaScript?

The async function helps to write promise-based code asynchronously via the event-loop. Async functions will always return a value. Await function can be used inside the asynchronous function to wait for the promise.

What is the difference between async and await in Node JS?

Async functions will always return a value. Await function can be used inside the asynchronous function to wait for the promise. This forces the code to wait until the promise returns a result. Install async from npm in Node.js using the following command:


1 Answers

So this one turned out to be one of those problems you feel really stupid about after you figure it out, but because of how long I spent struggling with it, I'll answer my own question so someone else can hopefully benefit.

It turns out the GraphQL resolver function has to return either a value or a promise that resolves to that value. So what I was trying to do with something like this:

var { graphql, buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
    type Query {
        data: String
    }
`);

// The root provides a resolver function for each API endpoint
var root = {
    data: () => {
        getData((data) => {
            return data;    // Returns from callback, instead of from resolver
        }
    }
};

// Run the GraphQL query '{ data }' and print out the response
graphql(schema, '{ data }', root).then((response) => {
    console.log(response);
});

Can be done with something like this:

var { graphql, buildSchema } = require('graphql');

// Construct a schema, using GraphQL schema language
var schema = buildSchema(`
    type Query {
        data: String
    }
`);

let promiseData = () => {
    return new Promise((resolve, reject) => {
        getData((data) => {
            resolve(data);
        });
    });
};

// The root provides a resolver function for each API endpoint
var root = {
    data: () => {
        return promiseData();
    }
};

// Run the GraphQL query '{ data }' and print out the response
graphql(schema, '{ data }', root).then((response) => {
    console.log(response);
});
like image 55
TheEnvironmentalist Avatar answered Sep 23 '22 04:09

TheEnvironmentalist