In this function, I want to check if there are any posts in the database made nearby to a set of input lat/long coords so that I can display them based on where the user currently is, and I also want to write a function to check if they are in a "too close" range (less than 2m or so).
I'm not sure how to do it properly and every answer I have found online after extensive research has given me nothing. I am using NodeJS 18 LTS with the latest version of mongodb.
This is the code I tried to get the posts
const getPostsInRange = (lng, lat) => {
// get all posts in range
const postCollection = db.collection('posts')
return postCollection.find({
"location": {
"$near": [parseFloat(lng), parseFloat(lat)],
"$maxDistance": 100000
}})
}
and here is the code that calls it, from index.js
app.get('/getposts/:lat/:long', requiresAuth(), (req, res) => {
const { lat, long } = req.params
getPostsInRange(long, lat)
.then((posts) => {
res.send(posts)
})
.catch((err) => {
console.log(err)
res.status(500).end()
})
what my data looks like in mongodb:
{
"textBody": "new message 3",
"image": "xxxx",
"location": {
"type": "Point",
"coordinates": [xxxx, xxxx]
},
"timestamp": 1674503437
}
I get errors such as
TypeError: getPostsInRange(...).then is not a function
, and similar but slightly different ones that Google seems to have never have heard of.
i would love some help building this project, full code snippets would be greatly appreciate due to my lack of experience working with mongodb.
CodePudding user response:
It looks like the issue is with the getPostsInRange function not returning a Promise, which is necessary for the .then and .catch to work. The find method from the MongoDB Node.js driver returns a Cursor, which is not a Promise but does have a toArray method that can be used to convert the results to an array and return a Promise.
Here is an example of how you can modify the getPostsInRange function to return a Promise:
const getPostsInRange = (lng, lat) => {
// get all posts in range
const postCollection = db.collection('posts')
return postCollection.find({
"location": {
"$near": [parseFloat(lng), parseFloat(lat)],
"$maxDistance": 100000
}
}).toArray();
}
This will make the getPostsInRange function return a Promise that resolves with an array of posts.
It is also worth mentioning that the $near operator requires MongoDB to have a 2dsphere index on the location field, which you can create by running the following command in your MongoDB shell:
db.posts.createIndex({ location: "2dsphere" })
Also you need to make sure that your location object in the document is in the correct format like {type:"Point",coordinates:[long,lat]}
.
Hope this helps!