GET-запрос Express.js не возвращает данные при первом вызове - PullRequest
0 голосов
/ 05 июня 2018

Я создаю приложение с использованием Node / Express / MongoDB (впервые со всеми этими), которое позволит мне извлекать данные из БД и отображать их на странице Express.Вот как выглядит запрос GET:

var str = "";

app.route('/view-reports').get(function(req, res) {
  var cursor = collections.find({});

  cursor.each(function(err, item) {
    if (item != null) {
      console.log(str);
      str = str + "Substance: " + item.substance + "<br>";
    }
    if (err) {
      console.log(err);
    }
  });
  console.log(str);
  res.send(str);
  str = "";
});

Я ожидаю, что это вернет что-то вроде этого:

Вещество: a

Вещество: b

Вещество: c

Однако первоначальный запрос вообще ничего не возвращает.Второй запрос вернет вышеуказанное.Если я заключу res.send(str) в условное условие if, оно просто не загрузится, пока не будет сделан второй запрос.

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Создайте роутер специально для веществ и используйте его в приложении.Вместо разрывов вы можете также создать ul, чтобы обработка выполнялась на внешнем интерфейсе.Разделите ваши проблемы.Серверу не нужно беспокоиться о каком-либо рендеринге и т. Д. Одна цель для процесса.

Маршрутизаторы могут создаваться для каждого ресурса.Создайте роутер для веществ, для кошек, для собак.У каждого отдельного роутера есть свои собственные пост-удаления и путы, которые позволяют вам изменять этот ресурс.app может использовать все маршрутизаторы одновременно.

app.use(catRouter); app.use(mooseRouter); app.use(platypusRouter);

const { Router } = require('express');
const createError = require('http-errors');
let substanceRouter = new Router();

function buildElement(arr)
{
  let start = '';
  arr.forEach(val => {
    if(!val) return;
    start += `Substance : ${val}<br>`;
  });
  return start;
}

subtanceRouter.get('/endpoint/whatever', function(req, res, next) {

  collectios.find({})
  
  .then(results => {
    if(!results) throw new Error('Resource Not Found');
    
    let output = buildElement(results);
    res.json(output);
    next();
  })
  
  .catch(err => next(createError(404, err.message)));
})

app.use(substanceRouter);

Поочередно мы можем написать:

let output = results
            .filter(sub => !!sub)
            .join('<br>');
res.json(output);

Но имейте в виду, что это увеличит накладные расходы памяти, создаст совершенно новый массив для размещения результатов, в худшем случае потребляя O (n) памяти.

0 голосов
/ 05 июня 2018

cursor.each() является асинхронным.Это означает, что иногда он запускается ПОЗЖЕ после вашего res.send(str), поэтому вы получаете предыдущую версию str.Сначала вам нужно собрать все данные, а затем отправлять свой ответ только тогда, когда у вас есть все данные.

Если вы хотите получить все данные, вы можете использовать обещания и .toArray(), например:

app.route('/view-reports').get(function(req, res) {
  collections.find({}).toArray().then(data => {
      let result = data.map(item => {
          return "Substance: " + item.substance + "<br>";
      }).join("");
      res.send(result);
  }).catch(err => {
      // database error
      console.log(err);
      res.sendStatus(500);
  });
});

Примечание: это также разумно избавляет от переменной str, которая находилась вне области запроса и, таким образом, могла легко привести к ошибке параллелизма, когда несколько запросов выполнялись одновременно (от разных пользователей).

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