8

I'm trying to find tours within a specific distance.here is my code

exports.getTourWithin = catchAsync(async (req, res, next) => {
  const { distance, latlng, unit } = req.params;
  const [lat, lng] = latlng.split(',');
  if (!lat || !lng) {
    next(
      new AppError(
        `please provide latitude amd longitude in the form of lat,lng`,
        400
      )
    );
  }
  const radius = unit === 'mi' ? distance / 3963.2 : distance / 6378.1;

  const tours = Tour.find({
    $geoWithin: { $centerSphere: [[lng, lat], radius] }
  });
  res.status(200).json({
    status: 'success',
    data: {
      data: tours
    }
  });
});

but i'm getting this error in postman:

"message": "Converting circular structure to JSON\n    --> starting at object with constructor 'NativeTopology'\n    |     property 's' -> object with constructor 'Object'\n    |     property 'sessionPool' -> object with constructor 'ServerSessionPool'\n    --- property 'topology' closes the circle",
    "stack": "TypeError: Converting circular structure to JSON\n    --> starting at object with constructor 'NativeTopology'\n    |     property 's' -> object with constructor 'Object'\n    |     property 'sessionPool' -> object with constructor 'ServerSessionPool'\n    --- property 'topology' closes the circle\n    at JSON.stringify (<anonymous>)\n    at stringify (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\response.js:1119:12)\n    at ServerResponse.json (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\response.js:260:14)\n    at D:\\Node-Jonas\\Node-Rest-Api\\controllers\\tourControllers.js:190:19\n    at D:\\Node-Jonas\\Node-Rest-Api\\utilis\\catchAsync.js:3:5\n    at Layer.handle [as handle_request] (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\layer.js:95:5)\n    at next (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\route.js:137:13)\n    at Route.dispatch (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\route.js:112:3)\n    at Layer.handle [as handle_request] (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\layer.js:95:5)\n    at D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\index.js:281:22\n    at param (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\index.js:354:14)\n    at param (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\index.js:365:14)\n    at param (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\index.js:365:14)\n    at param (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\index.js:365:14)\n    at Function.process_params (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\index.js:410:3)\n    at next (D:\\Node-Jonas\\Node-Rest-Api\\node_modules\\express\\lib\\router\\index.js:275:10)"
}

how i can solve this issue?Thanks

9 Answers 9

30

I came across this exact error. You need to add "await" to your call to the Tours model as you're using async/await. You also need to include the field name you're querying on per @Anatoly's point:

const tours = await Tour.find({
    yourfieldname: {
        $geoWithin: { $centerSphere: [[lng, lat], radius] }
    }
});
Sign up to request clarification or add additional context in comments.

Comments

4

In my case, I forget to put await in front of find() operation of mongo in a controller . It worked for me after adding await in that statement So it returned promise instead of desired results

for good understanding, read it once https://www.geeksforgeeks.org/mongodb-db-collection-find-method/

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
3

You just need to add await before the find() function.

Comments

2

In tours you got a cursor not the data themselves. You should call toArray to retrieve the data.

const tours = Tour.find({
    $geoWithin: { $centerSphere: [[lng, lat], radius] }
  });
res.status(200).json({
    status: 'success',
    data: {
      data: tours.toArray()
    }
  });

5 Comments

Thanks for your reply but after trying your code it's said ""message": "tours.toArray is not a function","
Hmm. Can you look at tours content by setting a breakpoint at res.status line?
i missed to use await before Tour.find({ $geoWithin: { $centerSphere: [[lng, lat], radius] } }); after using await now i'm getting different error message ""message": "unknown top level operator: $geoWithin","
You didn't indicate a field before $geoWithin operator
Thanks Anatoly.i already fixed that but really thanks for your times and concerns.
1

I missing await in the async function by adding await this finding the search id

1 Comment

This is same as the previous answers, and an answer to a question with an already accepted answer. Please check other answers before answering a question.
0

Since you are using Async so you have to add await in Find() function. In my case, the same error was occurred and solved by await.

Comments

0

For me I missing await in the async function

// Delete Data 
 app.delete('/todos/delete/:id', async (req, res) => {
    const result =Todo.findByIdAndDelete(req.params.id)
    res.json(result)
 })

Fixed By Add await then it worked fine

// Delete Data 
app.delete('/todos/delete/:id', async (req, res) => {
   const result = await Todo.findByIdAndDelete(req.params.id)
   res.json(result)
})

Comments

0

tour.find will be executed asynchronously so we should handle the requests by then and catch.

3 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
Hi, in the accepted answer there is await Tour.find. It perfectly handles async code
yes, as the compilation stops until the query gets compiled it works perfectly
-1

You may miss "await" keyword.

1 Comment

This is the same solution as in this other answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.