Ошибка цепочки экспресс-обещаний

#javascript #mongodb #rest #api #express

#javascript #mongodb #rest #API #экспресс

Вопрос:

Я написал простой express.js сервер, который обрабатывает запросы REST API и извлекает данные из базы данных MongoDB. Когда я делаю запрос GET к определенной конечной точке («localhost: 8081 / api / getUserData»), цепочка обещаний работает не так, как я хочу, и я все еще не понимаю.

Это ошибка, которую я получаю: «[TypeError: не удается прочитать свойство ‘db’ из неопределенного]»

 var MongoClient = require('mongodb').MongoClient;
var express = require('express');
var app = express();
var rp = require("request-promise");
var cors = require('cors');

// use it before all route definitions
app.use(cors({ origin: '*' }));

/********************** REST API FUNCTIONS **********************/
app.get('/api/getUserData', function (req, res, next) {
  var context = {};
  console.log("in api getUserData")
  context.db_url = 'mongodb://localhost:27017/test';
  openDatabaseConnection(context)
    .then(getAllUserLocations)
    .then(closeDatabaseConnection)
    .then(function (context) {
      res.send(context.userLocations)
    })
    .catch(function (error) {
      console.log("ERROR :");
      console.log(error);
    })
})
/********************** END REST API FUNCTIONS **********************/

function getAllUserLocations(context) {
  context.db.collection("test").find().toArray().then(function (err, result) {
    console.log("Received from db: "   result.length   " objects");
    context.userLocations = resu<
    return context;
  });
}

function openDatabaseConnection(context) {
  console.log("Opening DB connection...");
  return MongoClient.connect(context.db_url)
    .then(function (db) {
      console.log("DB connection opened.");
      context.db = db;
      return context;
    })
}

function closeDatabaseConnection(context) {
  console.log("Closing DB connection");
  return context.db.close()
    .then(function () {
      console.log("DB connection closed");
      return context;
    })
}

/********************** STARTING SERVER **********************/
var server = app.listen(8081, function () {
  var host = server.address().address
  var port = server.address().port
  console.log("Githex server listening at http://%s:%s", host, port)
})
  

Буду признателен за любую помощь, и даже больше с объяснением, потому что я не понимаю, что я сделал не так.

Спасибо!

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

1. Поскольку context определяется как объект с одним db_url свойством, у него нет db свойства, когда вы используете его в своей getAllUserLocations функции

2. К сожалению, это не так. Я удалил из предоставленного мной кода другой обработчик запроса api, который работает без указания свойства ‘db’. Я только что попытался добавить свойство db перед цепочкой обещаний, но это тоже не решает проблему..

3. Вы правы, ошибка указывает на то, что context не определено в одной из ваших функций, и она не может «прочитать свойство ‘db’ из неопределенного» , и, вероятно, оно поставляется с номером строки и более конкретной информацией о том, где.

4. Например, getAllUserLocations() на самом деле ничего не возвращает, это должно быть return context.db.collection(... при условии, что функция также возвращает обещание.

5. Да, я добавил «return context.db» и т.д., И это решило проблему, но теперь возникла другая ^^, я попытаюсь решить эту проблему сейчас. Большое спасибо!

Ответ №1:

Точно так же, как @adeneo упоминал в первом комментарии, вам не хватает свойства db. Посмотрите на свою первую функцию:

 app.get('/api/getUserData', function (req, res, next) {
  var context = {};
  console.log("in api getUserData")
  context.db_url = 'mongodb://localhost:27017/test';
  openDatabaseConnection(context)
    .then(getAllUserLocations)
    .then(closeDatabaseConnection)
    .then(function (context) {
      res.send(context.userLocations)
    })
    .catch(function (error) {
      console.log("ERROR :");
      console.log(error);
    })
});
  

Теперь просматриваем строки внутри этой функции:

  1. Вы настраиваете context как пустой объект
  2. Вы добавили свойство db_url к объекту, пока у вас есть

     context = {db_url: "mongodb://localhost:27017/test}
      
  3. Вы передаете объект контекста в функцию openDatabaseConnection
  4. В функции openDatabaseConnection вы возвращаете контекстный объект. Этот новый возвращаемый объект нигде не устанавливается, он просто возвращается и никогда не используется. Вы хотите вызвать функцию getuserlocation() с этим возвращаемым значением.

Итак, вместо того, чтобы просто вызывать

 .then(getAllUserConnection)
  

Я бы сделал

 .then(function(context){getAllUserConnection(context);})
  

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