1
votes

I'm building a GraphQL API, where I need to access nearby users locations. I using the node-georedis lib (https://github.com/arjunmehta/node-georedis), which takes callbacks in order to get return data.

I can verify that the callback does indeed get called with the correct information returned, however when I then try to return that data in the GraphQL query resolver it's undefined. I figured it was an asynchronous issue, but I've tried various Promise based, await/async, and even a synchronous implementations after searching stackoverflow with no success.

Maybe I'm overlooking a scope issue?? Any thoughts would be greatly appreciated!

Query: {
    nearbyUsers: async (
        _,
        { input }: GQL.INearbyUsersOnQueryArguments
    ) => {
        return nearbyUsers(input.latitude, input.longitude);
    }

},



export const nearbyUsers = (latitude: Number, longitude: Number) => {
let users: any[] = [];

georedis.nearby({ latitude, longitude }, 5000, async (err: any, userIDS: any) => {

    if (err) {
        console.log(err);
    } else {
        users = await User.findByIds(userIDS);
        console.log(users); // Does indeed print proper Users
    }
});

return users; // Value is [] when returning

};

2

2 Answers

3
votes
export const nearbyUsers = (latitude: Number, longitude: Number) => {
    return new Promise((resolve, reject) => {
        georedis.nearby({ latitude, longitude }, 5000, (err: any, userIDS: any) => {
            err ? reject(err) : resolve(userIDS);
        });
    }).then(async (userIDS) => {
        return User.findByIds(userIDS as string[]);
    }); 
};
0
votes

What's important to add the answer from andrewwx10 here is that when 'georedis.nearby' is invoked, that function itself has a callback, and graphql won't wait til that callback is done before proceeding to the last 'return users; ' line..that's why the resolver returns empty.

Putting await code in the callback itself, just helps control flow within the callback itself, but not in the parent / top-level code flow here.

For this reason, it's imperative to wrap the invokation of georedis.nearby into a Promise so that the resolver doesn't keep going after the invokation.