Skip to content

graphql resolver return Cannot return null for non-nullable field from asynchronous function in nodejs

Don’t get me wrong I have been forced to use waterfall because I need to execute one function after another. There is no problem related to the schema or return type just stuck with asynchronous waterfall. All I need is to return from the final function not before.

const async = require('async')
module.exports = {
logout : ()=>{
        return async.waterfall([
            callback => {
                setTimeout(() => {
                    let data = 1;
                    return callback(null, data)
                }, 2000);
            },
            (data, callback) => {
                setTimeout(() => {
                    return callback(null, data+1)
                }, 2000);
            }
            
        ], (err, res)=>{
            console.log(res)
            return res
        })
    }
}

response from graphiql because It returns early. And console.log is working

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field RootMutation.logout.",
      "locations": [
        {
          "line": 4,
          "column": 3
        }
      ],
      "path": [
        "logout"
      ]
    }
  ],
  "data": null
}

Answer

Could you use async/await here? Along the lines of the below

async function logout(){
       let data = await new Promise((resolve,reject) => {setTimeout(() => { resolve(1)},2000)});
       
         data = await new Promise((resolve,reject) => {setTimeout(() => { resolve(data + 1)},2000)});
return data;
}

async function foo() {
    let res = await logout();
  alert(res)
}

foo()

Also I’m not familiar with the async library, but should you actually be returning the async.waterfall() call in your example as that returns undefined according to the docs.

Perhaps just

const async = require('async')
module.exports = {
logout : ()=>{
        async.waterfall([
            callback => {
                setTimeout(() => {
                    let data = 1;
                    return callback(null, data)
                }, 2000);
            },
            (data, callback) => {
                setTimeout(() => {
                    return callback(null, data+1)
                }, 2000);
            }
            
        ], (err, res)=>{
            console.log(res)
            return res
        })
    }
}

If not perhaps share what GraphQL library you are using as well