Duong Bach
Duong Bach

Reputation: 155

Express with mongodb find one

Im new to nodejs , express and mongodb. I got stuck at the findOne function using ObjectId of mongodb

With the code below, I got the error : "Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters" Im using lastest version of everything (because Im new to them)

enter image description here

My code in view:

<% for(var i = 0 ; i < posts.length; i++ ) {  %>
                  <% post = posts[i] %>
                  <article class="post">
                    <div class="post-preview col-xs-10 no-gutter">
                      <h2>
                        <a href="/posts/<%=i%>">
                          <%= post.title %>
                        </a>
                      </h2>
                      <p><%= post.description %></p>
                      <p class="meta">
                        <a href="author.html"><%= post.author.name %></a> in
                        <a href="category.html"><%= post.category.name %></a> <i class="link-spacer"></i> <i class="fa fa-bookmark"></i> <%= post.created_at %>
                      </p>
                    </div>
                    <div class=" col-xs-2 no-gutter">
                      <img src="<%= post.author.image %>" class="user-icon" alt="user-image">
                    </div>
                  </article>
                <% } %>

Please tell me what's wrong with my code . p/s : the req.params.id is valid and logable.

Upvotes: 1

Views: 2318

Answers (2)

Jeremy Pridemore
Jeremy Pridemore

Reputation: 1995

I'm guessing it's because the id is a string of not 12 bytes (nor 24 hex characters). When the URL comes in to your express web server, it's a string. When express matches a part of it and stores it, there's no rule that :id couldn't be myCoolId, which isn't a number.

So everything in req.params is a string. I would add some checking to make sure it's a number, cast it, and then give it to ObjectId.

EDIT: If you want to work with it as strings, then try some of the following:

const ObjectID = require('mongodb').ObjectID;

// When making a brand new record, just use a new object id.
let record = new ObjectID();
console.log(record);

// When giving the ID to the client as a string, make it a hex string.
let hexString = record.toHexString();
console.log(hexString);

// You can validate that it's a valid object id in your route when they post it back.
let valid = ObjectID.isValid(hexString);
console.log(valid);

// Then you can turn it back into an object id.
let fromHex = ObjectID.createFromHexString(hexString);
console.log(fromHex);

Upvotes: 0

chrisbajorin
chrisbajorin

Reputation: 6153

Default mongo IDs don't increment from 1. They will look like "_id" : ObjectId("5908f94c06515dfa8522459c") in the database. Your problem is your href is navigating by index, not the id itself. You need to change:

<a href="/posts/<%=i%>">
  <%= post.title %>
</a>

to:

<a href="/posts/<%=post._id%>">
  <%= post.title %>
</a>

this will make your link /posts/5908f94c06515dfa8522459c instead of /posts/1

Upvotes: 2

Related Questions