Estoy creando un método PUT para actualizar un conjunto dado de datos; sin embargo, en mi función de actualización, req.body no está definido.
controlador.js
async function reviewExists(req, res, next) { const message = { error: `Review cannot be found.` }; const { reviewId } = req.params; if (!reviewId) return next(message); let review = await ReviewsService.getReviewById(reviewId); if (!review) { return res.status(404).json(message); } res.locals.review = review; next(); } async function update(req, res, next) { console.log(req.body); const knexInstance = req.app.get('db'); const { review: { review_id: reviewId, ...review }, } = res.locals; const updatedReview = { ...review, ...req.body.data }; const newReview = await ReviewsService.updateReview( reviewId, updatedReview, knexInstance ); res.json({ data: newReview }); }servicio.js
const getReviewById = (reviewId) => knex('reviews').select('*').where({ review_id: reviewId }).first(); const updateReview = (reviewId, updatedReview) => knex('reviews') .select('*') .where({ review_id: reviewId }) .update(updatedReview, '*');Cómo debería verse:
"data": { "review_id": 1, "content": "New content...", "score": 3, "created_at": "2021-02-23T20:48:13.315Z", "updated_at": "2021-02-23T20:48:13.315Z", "critic_id": 1, "movie_id": 1, "critic": { "critic_id": 1, "preferred_name": "Chana", "surname": "Gibson", "organization_name": "Film Frenzy", "created_at": "2021-02-23T20:48:13.308Z", "updated_at": "2021-02-23T20:48:13.308Z" }La primera función en la que verifico si existe una revisión funciona con mi método de eliminación. ¿Me estoy perdiendo algo en una de estas funciones que haría que req.body no esté definido?
Nadie en las otras respuestas realmente explica el "por qué" aquí. De forma predeterminada req.body no está undefined o está vacío y el motor Express no lee el cuerpo de la solicitud entrante.
Entonces, si desea saber qué hay en el cuerpo de la solicitud y, aún más, si desea que se lea y luego se analice en req.body para poder acceder directamente allí, entonces necesita instalar el middleware apropiado que verá qué tipo de solicitud es y si ese es el tipo de solicitud que tiene un cuerpo (como POST o PUT) y luego observará el tipo de contenido entrante y verá si es un tipo de contenido que sabe cómo analizar , entonces ese middleware leerá el cuerpo de la solicitud, lo analizará y colocará los resultados analizados en req.body para que esté allí cuando se llame a su controlador de solicitud. Si no tiene este tipo de middleware instalado, req.body no estará undefined o estará vacío.
Express tiene un middleware como este incorporado para varios tipos de contenido. Puede leer sobre ellos aquí en el documento Express. Hay middleware para los siguientes tipos de contenido:
express.json(...) for "application/json" express.raw(...) reads the body into a Buffer for you to parse yourself express.text(...) for "text/plain" - reads the body into a string express.urlencoded(...) for "application/x-www-form-urlencoded" Por lo tanto, necesitará algún middleware para analizar su contenido específico para que pueda acceder a él en req.body . No dice exactamente el tipo de datos que está usando, pero según sus expectativas de datos, supongo que tal vez sea JSON. Para eso, colocarías esto:
app.use(express.json());En algún lugar antes de su controlador de solicitud PUT. Si su formato de datos es diferente, entonces podría usar una de las otras opciones de middleware integradas.
Tenga en cuenta que para otros tipos de datos, como la carga de archivos y demás, existen módulos completos, como multer , para leer y analizar esos tipos de datos en propiedades que su controlador de solicitudes puede ofrecer.
Deberías usar un analizador de cuerpo. Básicamente, Express no puede saber cómo analizar los datos entrantes que los usuarios le arrojan, por lo que debe analizar los datos. Afortunadamente, hay algunos analizadores de cuerpo (y durante bastante tiempo, los analizadores de cuerpo para JSON y UrlEncoded (no estoy seguro de si hay otros) están integrados en Express). La forma de hacerlo es agregar un middleware en su aplicación express así:
const app = express(); ... app.use(express.json({ type: "*/*" // optional, only if you want to be sure that everything is parsed as JSON. Wouldn't recommend })); ... // the rest of the express appAsegúrese de tener instalado el middleware body-parser , que extrae el cuerpo del flujo de solicitud y lo expone en req.body ( fuente )
npm install body-parser --saveAsí es como se verían las definiciones del servidor express:
var express = require('express') var bodyParser = require('body-parser') var app = express() // parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })) // parse application/json app.use(bodyParser.json())