#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.