Reputation: 55
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
};
Upvotes: 1
Views: 623
Reputation: 914
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.
Upvotes: 0
Reputation: 55
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[]);
});
};
Upvotes: 3