Неопределенное тело в запросе PUT

У меня есть приложение React/Redux/Node, которое отправляет запрос на обновление пользователя:

client/src/components/pages/AlignmentPage.tsx:

const AlignmentPage = () => {
  const dispatch = useAppDispatch();
  const [alignment, setAlignment] = useState("");
  const user: User | null = useAppSelector(
    (state: RootState) => state.userData.user
  );

  const handleSetAlignment = (value: string) => {
    setAlignment(value);
    displayNewAlignment(value);
    if (user) {
      console.info("in AlignmentPage.tsx:", { alignment: value });
      dispatch(updateUser(user._id, { alignment: value }));
    }
  };
...

В моем действии Redux мы вызываем конечную точку PUT для пользователя:

export const updateUser = (userId: string, data: any) => async (dispatch: any) => {
  try {
    dispatch(setLoadingAction(true));

    const response = await fetch(`http://localhost:5000/api/user/${userId}`, {
      method: 'PUT',
      cache: 'no-cache',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data)
    });

    const updatedData = await response.json();
    dispatch(updateUserAction(updatedData.user));
  } catch (error) {
    dispatch(setErrorAction('error updating user!'));
  }
}

Конечная точка контроллера выглядит следующим образом:

exports.updateUser = asyncHandler(async (req: any, res: any, next: any) => {
  const { userId } = req.params;
  console.info(req.body)
  const data = req.body;

  const user = await updateUser(userId, data);

  res.status(200).json({ user });
});

По какой-то причине в контроллере я могу нормально выйти из параметра userId. Но тело всегда возвращает undefined и поэтому хранилище Redux и Document в Mongo не обновляются. Я могу успешно регистрировать «данные» до вызова const response = await fetch(http://localhost:5000/api/user/${userId}" в действии Redux. Регистратор updatedData возвращает исходный объект MongoDB, но без обновленного поля («выравнивание»):

Object { user: {…} }
​user: Object { _id: "65d73ae14d1a69c64d6787e6", ipAddress: "::ffff:127.0.0.1", createdAt: "2024-02-22T12:15:29.745Z", … }
​​__v: 0
​​_id: "65d73ae14d1a69c64d6787e6"
​​alignment: ""
​​createdAt: "2024-02-22T12:15:29.745Z"
​ipAddress: "::ffff:127.0.0.1"

Такое впечатление, что что-то мешает отправить тело на контроллер. Я не уверен, так ли я настраиваю роутер или что. Я где-то читал, что это может быть связано с тем, что на стороне сервера не установлено промежуточное программное обеспечение bodyParser, поэтому я реализовал это в своем файле server.ts, но, похоже, это не решило проблему.

(async () => {
  const port = env.PORT;
  app.use(express.json());
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: false }));
  app.use('/api/user', userRouter);

  try {
    app.listen(port, () => {
      db.on("error", console.error.bind(console, "connection error:"));
      db.on("connected", function () {
        console.info("Connected to MongoDB");
      });
      console.info(`Server started at http://localhost:${port}`);
    });
  } catch (err) {
    const error = new Error("Request failed");
    console.info(err);
    throw error;
  } finally {
    console.info("Server started");
  }
})();

api/src/routes/user.ts:

router.get("/api/user", userController.getUser);
router.put("/api/user/:userId", userController.updateUser);

export { router };

Добавлены скриншоты логгеров и полезной нагрузки redux:

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я понял.

Мне нужно было передать express.json() в качестве аргумента при вызове конечной точки пользовательского контроллера.

api/src/routes/user.ts:

router.put("/api/user/:userId", express.json(), userController.updateUser);

api/src/controllers/user.ts:

exports.updateUser = asyncHandler(async (req: any, res: any, next: any) => {
  const { userId } = req.params;
  const data = req.body;

  const user = await updateUser(userId, data);

  res.status(200).json({ user });
});

Данные успешно обновляются :)

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