2

I have a document with an array of subdocuments:

{
  "company": "test plc",
  "address": [
    {
      "addr1": "37",
      "addr2": "",
      "addr3": "test",
      "addr4": "",
      "addrcity": "",
      "addrcounty": "test",
      "addrpostcode": "test"
    },
    {
      "addr1": "37",
      "addr2": "",
      "addr3": "test",
      "addr4": "",
      "addrcity": "",
      "addrcounty": "test",
      "addrpostcode": "test"
    },
    {
      "addr1": "37",
      "addr2": "",
      "addr3": "test",
      "addr4": "",
      "addrcity": "",
      "addrcounty": "test",
      "addrpostcode": "test"
    }
  ],
  "contacts": [
    {
      "name": "test",
      "surname": "testing",
      "title": "master"
    },
    {
      "name": "test",
      "surname": "testing",
      "title": "master"
    }
  ]
}

What I would like to do is return a list of documents by searching the contacts.surname property.

var leads = Lead.find({"contact.surname":req.params.name});

This causes an error "Converting circular structure to JSON" but I am not sure why.

added on edit:

This is my collection schema:

var leadsSchema = new Schema({
  company: String,
  address:
  [
    {
      addr1: String,
      addr2: String,
      addr3: String,
      addr4: String,
      addrcity: String,
      addrcounty: String,
      addrpostcode: String
    }
  ],
  contacts:
  [
    {
      name: String,
      surname: String,
      title: String
    }
  ]
});
var Lead = mongoose.model('leads', leadsSchema);

Here are my two routers:

This returns all from the collection find:

router.get('/', function(req, res) {
  Lead.find({}).exec(function(err, leads) {
    res.send(leads);
  });
});

This causes the circular error:

router.get('/findByContactName/:surname', function(req, res) {
  var leads = Lead.find({"contacts.surname":req.params.name});
  res.send(leads);
});
Teemu Leisti
  • 3,750
  • 2
  • 30
  • 39
Dominic Scanlan
  • 1,009
  • 1
  • 6
  • 12

3 Answers3

23

TL;DR:

Change var leads = Lead.find({"contacts.surname":req.params.name});

To:

var leads = await Lead.find({"contacts.surname":req.params.name});

Explanation

model.find() just returns a query. It does not execute the query for you. So, 'leads' variable is currently a Mongoose query document.

When you do res.send(leads), express internally does this:

JSON.stringify(leads)

stringify() cannot convert circular structures to JSON. Hence, the error.

If someone here could shed light on why Mongoose query document is a circular structure, that would be great!

Amey
  • 460
  • 1
  • 4
  • 9
10

try this

router.get('/findByContactName/:surname', function(req, res){
Lead.find({"contacts.surname":req.params.name}).exec(function(err, leads){
res.send(leads);
});
Kevin Brady
  • 1,684
  • 17
  • 30
  • Ah good spot. I think it was a typo though when adding this question. Updated to: var leads = Lead.find({"contacts.surname":req.params.name}); res.send(leads); but still same error – Dominic Scanlan Feb 03 '15 at 11:23
  • Check out this SO article to try and track down what field is causing the circulat structure. (is req.params.name just a string value?) http://stackoverflow.com/questions/7005205/converting-circular-structure-to-json-any-way-to-find-what-field-it-is-compla – Kevin Brady Feb 03 '15 at 11:29
  • yes. I've even tried Lead.find({"contact.surname":"testing"}); – Dominic Scanlan Feb 03 '15 at 11:35
  • does the query work from the mongo shell? If so, then you can rule out that the query or the DB is the issue. can you provide more of the code surrounding the DB call you are making? – Kevin Brady Feb 03 '15 at 11:42
  • thanks for the suggestion. Yes the shell returns the row i was expecting. – Dominic Scanlan Feb 03 '15 at 11:55
  • can you provide more code before and after the DB call so to see if we can identify where the circular structure error is coming from – Kevin Brady Feb 03 '15 at 12:09
5

Or try this

 router.get('/findByContactName/:surname', async (req, res)=> {
      const leads = await Lead.find({"contacts.surname": req.params.surname });
      res.send(leads);
    });
Community
  • 1
  • 1
U.A
  • 2,991
  • 3
  • 24
  • 36
  • 1
    This should be higher up! The mongoose model relies on asynchronous functions, so we would need to await them before carrying on. – Jason Feb 18 '22 at 22:01