Express Middleware: ОШИБКА: TypeError: Преобразование циклической структуры в JSON

Я использую следующую функцию в качестве промежуточного программного обеспечения только для увеличения идентификатора нового объекта, добавляемого в мой массив:

let lions = []
let id = 0

const updateId = function(req, res, next) {
  if (!req.body.id) {
    id++;
    req.body.id = id + '';
  }
  next();
};

Когда я публикую нового льва, он попадает по этому маршруту:

app.post('/lions', updateId, (req, res) => {
  console.info('POST req', req.body)
  const lion = req.body;
  lions.push(lion)

  res.json(req)
})

POST работает, и новый лев создается, однако я получаю следующую ошибку. Любые идеи о том, как это исправить?

[nodemon] starting node server.js NODE RUNNING on port: 3000 GET lions: [] ERROR: TypeError: Converting circular structure to JSON at JSON.stringify () at stringify (/Users/leongaban/projects/tutorials/pluralsight/api-design-node/node_modules/express/lib/response.js:1119:12)

сервер.js

// create a route middleware for POST /lions that will increment and
// add an id to the incoming new lion object on req.body

const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const port = 3000

app.use(express.static('client'))
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())

let lions = []
let id = 0

const updateId = function(req, res, next) {
  if (!req.body.id) {
    id++;
    req.body.id = id + '';
  }
  next();
};

app.param('id', (req, res, next, id) => {
  let lion = lions.filter((lion => lion.id === id))

  if (lion) {
    req.lion = lion;
    next();
  }
  else {
    console.info('NO LION')
    res.send()
  }
})

app.get('/lions', (req, res, next) => {
  console.info('GET lions:', lions)
  res.json(lions)
})

app.get('/lions/:id', (req, res) => {
  res.json(req || {})
})

app.post('/lions', updateId, (req, res) => {
  console.info('POST req', req.body)
  const lion = req.body;
  lions.push(lion)

  res.json(req)
})

app.put('/lions/:id', (req, res) => {
  const paramId = req.params.id
  const updated = req.body

  if (updated.id) delete updated.id

  const oldLion = lions.find((lion => lion.id === paramId))

  if (!oldLion) res.send()

  const newLion = Object.assign({ id: oldLion.id }, updated)
  lions = lions.filter(lion => lion.id !== paramId)
  lions.push(newLion)

  res.json(newLion)
})

app.delete('/lions/:id', (req, res) => {
  lions = lions.filter((lion => lion.id !== req.params.id))

  res.json(lions)
})

app.use((err, req, res, next) => {
  console.error('ERROR:', err)
})

app.listen(port, () => console.info(`NODE RUNNING on port: ${port}`))

Может быть, может быть, потому что в этой строке: res.json(req) метода app.post() объект req содержит внутреннее свойство, ссылающееся на внешнее, таким образом создавая циклическую ссылку. Проверьте структуру этого объекта с помощью console.info() или, возможно, вы сможете избежать проблемы, если вернете в ответ что-то другое.

Shidersz 03.04.2019 21:50

Может быть, это тоже может помочь: stackoverflow.com/questions/11616630/…

Shidersz 03.04.2019 21:53

@Shidersz, вы были правы, опубликовав, что я сделал, чтобы решить проблему, но вы хотите опубликовать свой ответ? Я проверю его.

Leon Gaban 03.04.2019 22:01

Извините, но я не вижу четкого способа дать ответ на этот вопрос в предоставленном вами контексте. Однако я рад, что гипотеза о возможной проблеме помогает вам.

Shidersz 03.04.2019 22:12
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
4
12 213
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Could be, maybe, because on this line: res.json(req) of the app.post() method, the req object contains an inner property referencing an outer one thus creating a circular reference. Check the structure of that object with console.info() or maybe you can avoid the problem if you return other thing on the response.

– Shidersz

Необходимо создать новую переменную перед передачей ее в res.json функции put.

app.param('id', (req, res, next, id) => {
  let lion = lions.filter((lion => lion.id === id))
  
  if (lion) {
    req.lion = lion;
    next();
  } else {
    res.send();
  }
})

app.get('/lions', (req, res, next) => {
  console.info('GET lions:', lions)
  res.json(lions)
})

app.get('/lions/:id', (req, res) => {
  console.info('GET lion:', req.lion)
  const lion = req.lion // <-- here
  res.json(lion || {})  // <-- then here instead of passing req
})

Другие вопросы по теме