0

I'm learning Express/Mongo(using mLab) by building a simple little app that I can create a list of clients and a single client detail page.

localhost:3000/clients renders the entire collection of 'clients'

localhost:3000/clients/:id should render the specific client by id

This is a collection: clients entry example from MongoDB (mLab):

{
    "_id": {
        "$oid": "57ba01d3ab462a0aeec66646"
    },
    "name": "ClientName",
    "address": {
        "street": "StreetName",
        "city": "Cityname",
        "state": "Statename",
        "zip": "1234"
    },
    "createDate": {
        "$date": "2016-08-21T19:32:35.525Z"
    }
}

I successfully created an href on the /clients page with the id value that links to the specific client:

<a href="/clients/<%= client._id %>"><%= client.name %></a>

Which correctly results in this:

http://localhost:3000/clients/57ba01d3ab462a0aeec66646

Here is my get function for /clients/:id:

app.get('/clients/:id', (req, res) => {
  db.collection('clients').findOne(req.params.id, (err, result) => {
    if (err) {
      handleError(res, err.message, "Failed to get clients.");
    } else {
      console.log(result);
      res.render('client.ejs', {client: result})
    }
  });
})

Clicking on the link results in the following error:

MongoError: query selector must be an object at Function.MongoError.create (/Users/username/Desktop/node/node_modules/mongodb-core/lib/error.js:31:11) at Collection.find [...]

I've been reading and searching all afternoon and trying a ton of different options like:

Do I really need Mongoose? This seems like a foundational thing to do it Mongo — why isn't it working?

Community
  • 1
  • 1
chrstn
  • 1
  • 1
  • 3
  • Possible duplicate of [MongoDB $oid vs ObjectId](http://stackoverflow.com/questions/26938598/mongodb-oid-vs-objectid) – Mario Santini Aug 21 '16 at 21:26
  • That may be a duplicate, but since I don't know wtf I'm doing, I'm not familiar with the query on that question being in the form of json: `{ "_id": { "$in": [ { "$oid": "54651022bffebc03098b4567" }, { "$oid": "54651022bffebc03098b4568" } ] } }` – chrstn Aug 21 '16 at 21:35
  • 1
    Your filter criteria should be: *{"_id": { "$oid": req.params.id}}*. The issue is you're using *$oid* instead of normal plain *ObjectId*. – Mario Santini Aug 21 '16 at 21:40
  • It's slowly sinking in :/ . However, when I add what you outlined, I get a hard err: `db.collection('clients').findOne({"_id": { "$oid": req.params.id}}, (err, result) => {[...]` – chrstn Aug 21 '16 at 21:49
  • ^ That results in: `{"error":"Failed to get clients."}` – chrstn Aug 21 '16 at 21:50
  • Ok, sorry I forgot you should wrap your *res.params.id* with *mongo.ObjectId()* like: *mongo.ObjectId(res.params.id)*. Where *mongo* is the variable name of MongoDB package. – Mario Santini Aug 21 '16 at 21:53
  • That didn't seem to work. I ended up following this: http://stackoverflow.com/a/10929670/6286756 and stripping back out the inner {$oid: req.params.id}. This works: `var oi = new require('mongodb').ObjectID(req.params.id); db.collection('clients').findOne({"_id": oi}, (err, result) => {` – chrstn Aug 22 '16 at 01:43
  • Please write the answer as a post. – Mario Santini Aug 22 '16 at 05:15

3 Answers3

0

you need to use an object : {id: req.params.id}

app.get('/clients/:id', (req, res) => {
  db.collection('clients').findOne({_id: req.params.id}, (err, result) => {
    if (err) {
      handleError(res, err.message, "Failed to get clients.");
    } else {
      console.log(result);
      res.render('client.ejs', {client: result})
    }
  });
})
Mustapha Larhrouch
  • 3,373
  • 3
  • 14
  • 28
  • I had this at one point and while it no longer gives me the object error, I get a different error when trying to access the client.name on the page: `<%= client.name %>` The error I get is: `TypeError: client.ejs:16 14| 15| >> 16| <%= client.name %>` – chrstn Aug 21 '16 at 21:31
0

You need to convert req.params.id to MongoObject and then use it:

var id = new ObjectID(req.params.id);

Shantanu Madane
  • 617
  • 5
  • 14
0

Maybe something like:

 db.collection('clients').findOne({"_id.$oid": req.params.id}, (err, result) =>
Daphoque
  • 4,421
  • 1
  • 20
  • 31