Запрос NodeJS PUT возвращает ошибку 400 (неверный запрос)

#node.js #reactjs #express

#node.js #reactjs #экспресс

Вопрос:

Я пытаюсь выполнить запрос ввода с помощью NodeJS, Express и MongoDB. Проблема, с которой я в настоящее время сталкиваюсь, заключается в том, что я продолжаю получать error **400** , и я точно не уверен, почему.

Что я точно пытаюсь сделать, так это загрузить и отредактировать поле в моей коллекции USER после регистрации определенного пользователя. Это должно произойти на определенном /user/edit/:id маршруте.

Мое приложение структурировано по стандартному шаблону MVC.

Вот как структурирован мой Mongo Schema :

 let UserSchema = new mongoose.Schema({
  username: String,
  password: String,
  email: String,
  avatar: String,
  firstName: String,
  lastName: String,
  laps:[{ type: Schema.Types.ObjectId, ref: 'Stats' }]
});
  

Это мой сервис:

 exports.updateUser = async function(user) {
  let id = user.id;
  let oldUser;
  try {
    //Find the old User Object by the Id
    oldUser = await User.findById(id);
  } catch(e) {
    throw Error("Error occured while Finding the User");
  }
  // If no old User Object exists return false
  if (!oldUser) {
    return false;
  }
  //Edit the User Object
  oldUser.firstName = user.firstName || oldUser.firstName;
  oldUser.lastName = user.lastName || oldUser.lastName;
  oldUser.avatar = user.avatar || oldUser.avatar;
  try {
    let savedUser = await oldUser.save();
    return savedUser;
  } catch(e) {
    throw Error("And Error occured while updating the User");
  }
};
  

Контроллер, который я использую:

 exports.updateUser = async function(req, res, next) {
  if (!req.body._id){
    return res.status(400).json({status: 400, message: "Id must be present"})
  }
  let id = req.body._id;
  let user = {
    id,
    firstName: req.body.firstName || null,
    lastName: req.body.lastName || null,
    avatar: req.body.avatar || null
  };
  try {
    let updatedUser = await UserService.updateUser(user);
    return res.status(200).json({status: 200, data: updatedUser, message: "Successfully Updated User"})
  } catch(e) {
    return res.status(400).json({status: 400, message: e.message})
  }
};
  

Проложите путь в файле маршрутизатора:

 router.post('/edit/:id', UserController.updateUser);
  

Проложить путь для пользователей внутри файла сервера:

 app.use('/user', require('./api/routes/user.route'));
  

Я знаю, что большинство 4** ошибок приходят из интерфейсной части приложения, поэтому я также опубликую свою форму и конструктор, стоящий за ней. Я использую ReactJS в качестве фреймворка.

Форма интерфейса:

 class UserProfile extends Component {
  constructor(props) {
    super(props);
    this.state = {
      avatar: '',
      resultsSubmitted: false
    };
    this.formChange = this.formChange.bind(this);
    this.resultsSubmit = this.resultsSubmit.bind(this);
  }
  formChange(e) {
    console.log("form changed"   e.target);
    const { name, value } = e.target;
    this.setState({ [name]: value });
  }
  resultsSubmit(e) {
    e.preventDefault();
    const accessToken = JSON.parse(localStorage.getItem('auth_user')).data.access_token;
    const { avatar } = this.state;
    const { dispatch } = this.props;
    if (avatar) {
      console.log("submitting results: "   avatar);
      dispatch(userActions.addAvatar(avatar, accessToken));
    }
  }
  render(){
      const { avatar, resultsSubmitted} = this.state;
    return (
      <div className="container-fluid no-gutters page-login">
        <div className="row">
          <div className="login-wrapper">
            <h2> Edit User Profile </h2>

            <form onSubmit={this.resultsSubmit}>
              <div className="form-group">
                Paste Avatar URL: <input type="text" value={avatar} name="avatar" id="" onChange={this.formChange} />
              </div>
              <input type="submit" className="btn btn-primary btn-lg btn-block" value="submit"/>
            </form>

          </div>
        </div>
      </div>
    )
  }
}
function mapStateToProps(state) {
  const { layout } = state;
  return {
    layout
  };
}
export default connect(mapStateToProps)(UserProfile);
  

Моя отправка:

 function addAvatar(avatar, token) {
  return dispatch => {
    dispatch(request());
    userService.addAvatar(avatar, token)
      .then(
        user => {
          dispatch(success(user));
          history.push(`${process.env.PUBLIC_URL}/`);
        },
        error => {
          dispatch(failure(error));
          dispatch(alertActions.error(error));
        }
      );
  };
  function request() { return { type: userConstants.AVATAR_REQUEST } }
  function success(user) { return { type: userConstants.AVATAR_SUCCESS, user } }
  function failure(error) { return { type: userConstants.AVATAR_FAILURE, error } }
}
  

HTTP Post service:

 function addAvatar(avatar){
  const requestOptions = {
    method: 'POST',
    headers: authHeader(),
    body:  avatar
  };
  return fetch('http://localhost:3003/user/edit/:id', requestOptions)
    .then(response => {
      if (!response.ok) {
        console.log(" ",response," ");
        return Promise.reject(response.statusText);
      }else{
        console.log(response, "the user service response was gooooooooooood");
      }
      return response.json();
    })
    .then(data => console.log(data,"WHT DO WE HAVE HERE?"));
}
  

Прошу прощения за огромную стену кода, но я хотел включить все биты.

Я получаю сообщение об ошибке 400 (неверный запрос) при отправке маршрута http://localhost:3003/user/edit/:id

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

1. Какую ошибку вы получаете на вкладке Сеть инструментов разработчика? Это может быть проблема CORS.

2. Я думаю, это может быть связано с тем, что у id поля нет ключа в пользовательском объекте JSON, который вы создаете. Не могли бы вы попробовать изменить его на id: id и посмотреть, поможет ли это?

Ответ №1:

В вашем запросе на выборку вы отправляете только аватар в виде тела, а в вашей функции UpdateUser у вас есть следующий оператор if:

 if (!req.body._id){
    return res.status(400).json({status: 400, message: "Id must be present"})
}
  

итак, очевидно, что в вашем основном запросе указан не _id, а аватар, фактически вы отправляете свой id в качестве параметра

 'http://localhost:3003/user/edit/:id'
  

Таким образом, вы могли бы изменить эту строку в качестве обходного пути

 if (!req.params.id){
  

Надеюсь, это поможет.

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

1. да, но я получаю null в качестве входных данных откуда-то

Ответ №2:

Приведенный ниже фрагмент показывает, что вы пытаетесь получить параметр ID из тела запроса.

 if (!req.body._id){
    return res.status(400).json({status: 400, message: "Id must be present"})
}
  

Тогда как маршрут /user/edit/:id показывает, что параметр ID фактически передается через URL, и для доступа к нему все, что вам нужно, это получить свой ID из URL с помощью req.params.id . req.params содержит все параметры, которые передаются по маршруту или URL-адресу.

Приведенный выше фрагмент должен быть исправлен на;

 if (!req.params.id){
    return res.status(400).json({status: 400, message: "Id must be present"})
}
  

Проверьте https://expressjs.com/en/guide/routing.html#route-parameters для надлежащего руководства о том, как обращаться с параметром route.