Свойство Nodejs Mongodb — Document ‘Не определено’ при печати

#javascript #node.js #mongodb #express #promise

#javascript #node.js #mongodb #экспресс #обещание

Вопрос:

Я изучаю Node, Express и Mongodb, следовательно, очень новичок. Я разрабатываю форму, в которой есть текстовое поле, в которое пользователь будет добавлять данные.

Во-первых, мне нужно проверить, существуют ли эти данные или нет в главной таблице. Если существует, то я верну идентификатор записи, иначе я создам новую запись и верну ее идентификатор. Ниже приведен код, который я пробовал, но он выдает мне идентификатор как неопределенный.

code.js (контроллер)

 const toolsModel = require('../models/modTools');
const { validationResult } = require('express-validator');
module.exports = {
        async saveCode(req, res)
        {
            var promiseToolId = () => {
            return new Promise((resolve, reject) => {
            let tool_exist = toolsModel.findOne({ title: req.body.inpTool });

            if (tool_exist) {
                console.log('tool_exist'); // prints this line
                console.log(tool_exist._id); // gives undefined
                console.log(tool_exist); // prints the object.
                resolve(tool_exist._id);
            }
            else{
                console.log('tool not exist. inserting');
                var newTool = new toolsModel();
                newTool.insert({title: req.body.inpTool, created_at: new Date()}, function(err, newRec)              {
                if(err){
                    console.log('err while inserting');
                    console.log(err);
                    reject(err);
                }
                else{
                    console.log('inserted');
                    console.log(newRec);
                    resolve(newRec._id);
                }
                });
            }
            });
        };

        let errors = validationResult(req);
        if (!errors.isEmpty()){
            console.log('validation error');
            console.log(errors);
        }
        else{
            console.log('form is valid'); // prints this line

            // check if the tool exists in our database
            var toolId = await (promiseToolId()); //anything here is executed after result is resolved 
            console.log('toolId ', toolId); // prints undefined
        }
        }
};
  

modTools.js (модель)

 const mongoose = require('mongoose'),
    timeZone = require('mongoose-timezone'),
    Schema = mongoose.Schema;

const toolsSchema = new Schema({
    title: {type:String, required:true, trim: true},
    created_at: {type: Date, default: Date.now},
});

toolsSchema.plugin(timeZone);

module.exports = mongoose.model('developmentTools', toolsSchema);
  

Пожалуйста, обратите внимание, что я использую идентификатор автоматического увеличения для своей модели, которую я создал, используя приведенные ниже коды.

 db.createCollection("developmentTools");

db.developmentTools.insert ( {_id: "toolsId" , toolSeqValue : 0 } );


function getToolsNextID(seqName) {
  var seqDoc = db.developmentTools.findAndModify({
    query: { _id: seqName },
    update: { $inc: { toolSeqValue: 1 } },
    new: true
  });
  return seqDoc.toolSeqValue;
}
  

Я знаю, как я получаю доступ к свойству объекта tool_exist.title правильно, но не знаю, почему он дает мне undefined.

Я ошибаюсь в реализации обещания?

Пожалуйста, помогите.

С уважением,

Джавед Ансари

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

1. вы возвращаете обещание new Promise внутри async / await функции и даже не используете его .findOne() . там вы используете какой-то другой подход. вы используете старый подход обратного вызова. существует множество анти-шаблонов, которых следует избегать

2. @Ifaruki Я новичок в nodejs. Можете ли вы поделиться со мной некоторыми руководствами, в которых я могу узнать эффективный способ написания кодов в nodejs?

3. здесь stackoverflow.blog/2019/09/12/ … забудьте о «typescript» здесь, вы можете игнорировать его

Ответ №1:

Я могу решить проблему. Перечисление полного кода, если кто-то сталкивается с такой же проблемой. Большое спасибо @ifaruki за предоставление информативного URL-адреса и @slimane-amiar за его время.

 async saveCode(req, res)
    {
        async function createTool(tool_ttle){            
            var newTool = new toolsModel({
                title: tool_ttle,
                created_at: new Date()
            });

            return new Promise((resolve, reject) => {                
                newTool.save((err, newRec) => {
                    if(err){
                        console.log('err while inserting');
                        reject(err);
                    }
                    else{
                        console.log('inserted');
                        resolve(newRec);
                    }
                });                
            });
        }

        let errors = validationResult(req);
        if (!errors.isEmpty()){
            console.log('validation error');
            console.log(errors);
        }
        else{
            console.log('form is valid');
            
            toolTitle = req.body.inpTool;
            toolTitle = toolTitle.trim().toUpperCase();
            let toolRecord = '';

            // check if the tool exists in our database
            try {
                toolRecord = await toolsModel.findOne({ title: toolTitle });
                if (toolRecord){
                    console.log('tool_exist');
                    console.log(toolRecord);
                }
                else{
                    console.log('tool not exist. inserting');
                    toolRecord = await createTool(toolTitle);
                    if(toolRecord){
                        console.log('new tool is created below');
                        console.log(toolRecord);
                    }
                    else
                    {
                        console.log('error in creating new tool');
                        console.log(toolRecord);
                    }
                }
            }
            catch(error){
                console.log('in catch');
                console.log(error);
                return error;
            }

            console.log('proceeding further');            
        }
    }
  

Ответ №2:

Вы должны добавить await к запросу, поскольку он возвращает обещание, как показано ниже

 return new Promise( async (resolve, reject) => {
let tool_exist = await toolsModel.findOne({ title: req.body.inpTool });
  

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

1. Спасибо за ваше решение. Попробовал совет ur, но выдает ошибку, поскольку «ожидание допустимо только в асинхронной функции»

2. затем сделайте его асинхронным return new Promise( async (resolve, reject) => {