0

when i try to get my api via postman i have this error

TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'NativeTopology'
    |     property 's' -> object with constructor 'Object'
    |     property 'sessionPool' -> object with constructor 'ServerSessionPool'
    --- property 'topology' closes the circle

i use mongoose and express

const express = require('express')
const Rent = require('../model/rent')
var stringify = require('json-stringify-safe');

route = express()

route.use(express.json());

route.get('/rent', (req,res) => {
    const rents = Rent.find();
    res.send(JSON.stringify(rents))
})

module.exports = route

if i delete JSON.stringify i have the same problem Thank you in advance

chloy
  • 21
  • 1
  • 3

3 Answers3

0

Rent.find(); is probably returning a Promise and that is what you are trying to stringify there. What you could probably do is await the Promise for the actual value that is needed. This should do the trick:

const express = require('express')
const Rent = require('../model/rent')
var stringify = require('json-stringify-safe');

route = express()

route.use(express.json());

route.get('/rent', async (req,res) => {          // Made the controller into an `async` function to be able to use the `await` keyword
    const rents = await Rent.find();             // Await the Promise
    res.send(JSON.stringify(rents))
})

module.exports = route
zishone
  • 1,196
  • 1
  • 9
  • 11
0

SOLUTION #1

  1. Calling find on model Rent will return a Promise.
  2. We need to await for the Promise to resolve or get rejected in case of some error.
  3. Always put async\await code inside a try-catch block.
const express = require('express')
const Rent = require('../model/rent')

route = express()

route.use(express.json());

route.get('/rent', async (req, res) => {
  try {
    const rents = await Rent.find().exec();
    res.send(JSON.stringify(rents));
  } catch (error) {
    res.send({error: error.message});
  }  
})

module.exports = route;

SOLUTION #2: If you want the result in JSON format. This how I would code.

* node_modules
* app.js
* db.js
* src
  - routes
    - api_router.js

File path\to\project\app.js:

var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

const db = require("./db");

var apiRouter = require('./src/routes/api_router');

var app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/api', apiRouter);

module.exports = app;

File path\to\project\db.js:

const mongoose = require('mongoose');
const DB_URI = "mongodb://localhost:27017/backend_app";
const DB_OPTIONS = {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useFindAndModify: false,
  useCreateIndex: true
}

(async function () {
  try {
    await mongoose.connect(DB_URI, DB_OPTIONS);
    console.log("MONGOOSE: Connected to the database!");
  } catch (error) {
    console.log("MONGOOSE ERROR");
    console.log(error);
  }
})();

File path\to\project\src\routes\api_router.js:

const express = require('express');
const router = express.Router();

const Rent = require('../models/country_model')

router.get('/rent', async (req, res) => {
  try {
    const rents = await Rent.find().exec();
    res.status(200).json({ data: rents });           // <- Check this line.
  } catch (error) {
    res.status(500).json({ error: error.message });  // <- Check this line.
  }
})

module.exports = router;

Why find().exec()?

find().exec() on mongoose function will return an "real" Promise object. Read this.

Dheemanth Bhat
  • 4,269
  • 2
  • 21
  • 40
0

Try this:


route.get('/rent', (req,res) => {          
    Rent.find({}).then((rents)=>{
        res.send(rents)
    })           
})
NeNaD
  • 18,172
  • 8
  • 47
  • 89