1

The following code does not work:

try {
  const _id = req.params.id
  await req.user.populate("tasks").execPopulate();
  console.log("_id: ",_id)
  console.log("_id type", typeof(_id))
  //console.log(req.user.tasks);
  const task = await req.user.tasks.find(o =>
    o._id.toString() === _id)
  updates.forEach((update) => task[update] = req.body[update])
  await task.save();

Here is the console output:

_id:  5f1b5164acfd1a264d1589d5

src/routers/task.js:68
_id type string
src/routers/task.js:69
task: undefined

While if I change this line:

  const task = await req.user.tasks.find(o =>
    o._id.toString() === _id)

into this:

  const task = await req.user.tasks.find(o =>
    o._id.toString() === "5f1b5164acfd1a264d1589d5")

it works perfectly. Anyone know why?


Additional information: As asked in the comments, I looked at the exact characters in each string:

console.log(_id.split('').map(x => x.charCodeAt(0)))
/*
[
  53, 102, 49, 98, 53, 49, 54, 52, 97, 99,
  102, 100, 49, 97, 50, 54, 52, 100, 49, 53,
  56, 57, 100, 53, 10
]
*/

console.log("5f1b5164acfd1a264d1589d5".split('').map(x => x.charCodeAt(0)))
/*
[
  53, 102, 49, 98, 53, 49, 54, 52, 97, 99,
  102, 100, 49, 97, 50, 54, 52, 100, 49, 53,
  56, 57, 100, 53
]
*/
4
  • 2
    Are you 100% sure that o._id.toString() === _id doesn't work and o._id.toString() === "5f1b5164acfd1a264d1589d5" does? Because with the output that you showed (and with the string coming from an URL path parameter, so there won't be any BOM or newline issues or such) both of them should have worked. Just a feeling - maybe you originally didn't have the .toString() (because then it indeed wouldn't work becaue o._id is an ObjectId and not a string)?
    – CherryDT
    Commented Jul 24, 2020 at 22:38
  • I am 100% sure. Tried several times. Did another try just now. This is really bizarre.
    – hagenek
    Commented Jul 24, 2020 at 22:58
  • Check the output of _id.split('').map(x => x.charCodeAt(0)) and compare it to the same thing done with your string literal ("5f1b5164acfd1a264d1589d5".split('').map(x => x.charCodeAt(0))).
    – CherryDT
    Commented Jul 24, 2020 at 23:02
  • _id constant: [ 53, 102, 49, 98, 53, 49, 54, 52, 97, 99, 102, 100, 49, 97, 50, 54, 52, 100, 49, 53, 56, 57, 100, 53, 10 ] id string: [ 53, 102, 49, 98, 53, 49, 54, 52, 97, 99, 102, 100, 49, 97, 50, 54, 52, 100, 49, 53, 56, 57, 100, 53 ] This seems to be related to linefeed. I am on a windows machine, is that relevant?
    – hagenek
    Commented Jul 24, 2020 at 23:10

1 Answer 1

1

There is a newline character (character code 10, or \n in JavaScript) at the end of your _id value.

Actually this can even be seen in your debug output - there is an empty line after you print the ID. Instead of using console.log, I'd recommend using a debugger and stepping through the code and looking at variables this way. It would probably have displayed the string as "5f1b5164acfd1a264d1589d5\n" instead.

You can get rid of it using .trim, which removes all leading and trailing whitespace from a string:

const _id = req.params.id.trim()

This way, the code will work, despite the stray newline character passed into your URL.


However, this should make you wonder how that can even happen in the first place. I initially ruled out such a problem when I saw this question, because the _id seems to come from an URL path parameter req.params.id, and a newline is not a valid character in a URL, unless you explicitly pass it in as %0A which sounded unlikely to me at first. You should double-check where this URL comes from, because the actual bug probably originates from there!

2
  • Hi. The request comes from postman. I am on a windows machine, and I have downloaded source-files which I am now working in. Maybe some .js file has LF and not CRLF and it is causing problems?
    – hagenek
    Commented Jul 24, 2020 at 23:27
  • 1
    A newline character had been snuck into the url field I had in postman:
    – hagenek
    Commented Jul 27, 2020 at 15:28

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.