Попытка рендеринга шаблона на основе результата метода findOne() в mongoose schema

#node.js #mongodb #express #mongoose

#node.js #mongodb #выразить #mongoose

Вопрос:

Я пытаюсь использовать идентификатор задачи, сгенерированный в MongoDB, для отрисовки шаблона, который принимает идентификатор задачи в качестве входных данных. Я новичок в node и MongoDB, поэтому прошу прощения за любую неправильную терминологию. Метод findOne, приведенный ниже, возвращает null для параметра data в своей функции обратного вызова, хотя идентификатор задачи указан в URL.

Я пытался использовать exec() и chaining then(), но реализация не приводит к заполнению данных. Кроме того, версия MongoDB равна 3.4.

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

router.get('/createTask', function(req, res) {
  var newTask = new Task();

  newTask.save(function( err, data) {
    if (err) {
      console.log(err);
      res.render('error');
    } else {
      res.redirect('/task/'   data._id);
    }
  })
});

router.get('/task/:id', function(req, res) {
  if (req.params.id) {
    Task.findOne({_id: req.params.id}, function(err, data) {
      if (err) {
        console.log(err);
        res.render('error');
      }

      if (data) {
        res.render('task', {data: data});
      } else {
        res.render('error');
      }
    })
  } else {
    res.render('error');
  }
});

module.exports = router;
  

Это должно отобразить шаблон задачи с добавлением простого h1 для тестирования, но вместо этого возвращает пустую страницу.

Ответ №1:

Я предполагаю, что _id — это поле типа ObjectId, что означает, что вы не можете выполнить task.findOne({ _id: req.params.id }) и получить документ в аргументе data функции обратного вызова.

Вместо этого используйте переменную oId вместо req.params.id в task.findOne()

 const mongo = require('mongodb');
const oId = new mongo.ObjectID(req.params.id);
  

Комментарии:

1. Большое вам спасибо за ваш ответ! Я проверил тип поля в Robo 3T, и это действительно тип ObjectId. Другой альтернативой, которая работала, было добавление инструкции «return» ранее Task.findOne({ _id: req.params.id }) .

2. @Ron не могли бы вы добавить ответ, объясняющий, как использование оператора return перед Task.findOne() является альтернативой этому? А также было бы очень полезно для других, если бы вы могли, пожалуйста, отметить это как ответ, если вы так считаете, чтобы его можно было закрыть.