Я пишу многопользовательский онлайн-словарь. Я хочу внедрить доску лидеров, т.е. Атрибут "score" увеличивается, как только пользователь добавляет слово. У меня есть приблизительное представление о том, как это сделать, и я попробовал одно решение, однако оно не работает. Не могли бы вы направить меня?
Маршрут API Word
const express = require('express');
const router = express.Router();
const Word = require('../../models/Word');
const User = require('../../models/User');
const validateWordInput = require('../../validation/word');
const passport = require('passport');
// @route POST api/words
// @desc Add words to profile
// @access Private
router.post(
'/',
passport.authenticate('jwt', { session: false }),
(req, res) => {
const { errors, isValid } = validateWordInput(req.body);
// Check validation
if (!isValid) {
// Return any errors
return res.status(400).json(errors);
}
Word.find({}).then(word => {
if (
word.filter(
wrd =>
wrd.ugrWordCyr.toString().toLowerCase() ===
req.body.ugrWordCyr.toLowerCase()
).length !== 0
) {
return res
.status(404)
.json({ wordalreadyexists: 'Word already exists' });
} else {
const newWord = new Word({
user: req.user.id,
ugrWordCyr: req.body.ugrWordCyr,
rusTranslation: req.body.rusTranslation,
example: req.body.example,
exampleTranslation: req.body.exampleTranslation,
origin: req.body.origin,
sphere: req.body.sphere,
lexis: req.body.lexis,
grammar: req.body.grammar,
partOfSpeech: req.body.partOfSpeech,
style: req.body.style
});
newWord.save().then(word => res.json(word));
User.update(
{ _id: '5cf0cb78b3105d1ba8e30331' },
{ $inc: { score: 1 } }
);
}
});
}
);
Пользовательская модель
Здесь находится атрибут score
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create schema
const userSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
score: {
type: Number,
default: 0
},
avatar: {
type: String
},
date: {
type: Date,
default: Date.now
}
});
module.exports = User = mongoose.model('users', userSchema);
Я хочу, чтобы мое поле оценки обновлялось, когда новое слово добавляется через форму.





После успешного сохранения слова мы должны обновить количество пользователей.
Чтобы обновить оценку соответствующего пользователя, вы можете сделать следующее:
newWord.save().then((word) => {
//now update user model
User.findOne({ _id: req.user.id }) <-- or an id you would like
.then((foundUser) => {
foundUser.score = foundUser.score + 1
foundUser.save()
.then((savedUser) => {
res.json({ word, savedUser })
})
.catch((err) => {
return res.status(400).json({ error: "could not add score"})
})
})
.catch((err) => {
return res.status(400).json({ error: "could not find user"})
})
})
Вы получите сообщение об ошибке об отправке нескольких ответов, поскольку вы пытаетесь отправить один после слова «сохранить» и после обновления пользователя. Также мне было интересно, является ли хорошей практикой отправлять ответ клиенту до успешного завершения операций с базой данных?
@AsafAviv, это интересно, интересно, не лучше ли просто отправить один ответ в виде массива, включающего все ответы. OP, вероятно, придется обновить свои обработчики обещаний на интерфейсе, чтобы использовать их.
Однако получить второй ответ невозможно, потому что res.json звонит res.end
@AsafAviv, верно, так что, возможно, мы могли бы удалить первый res.json(), а затем передать слово response в объекте с сохраненным пользователем
Нет необходимости в массиве, мы можем отправить его как json после того, как мы обновим счет как res.json({ word, savedUser });
@AsafAviv спасибо, я не понял этого, прочитав это снова, ха-ха. :)
@ChristopherNgo, я попробовал ваш код, но, к сожалению, он не работает.
@NZMAI значение, вероятно, не отображается так, как вы хотите, во внешнем интерфейсе, вы получаете какие-либо ошибки при переходе по этому маршруту?
@ChristopherNgo, могу я спросить вас, где хранится значение «score»? В вашей реализации?
@NZMAI значение оценки должно исходить из модели пользователя. Поскольку мы можем найти пользователя с помощью User.findOne(), мы можем использовать возвращенные данные, которые мы называем foundUser. foundUser будет иметь свойство, называемое score. И мы просто обновляем счет, как задумано. Проблема, с которой вы можете столкнуться, заключается в том, что вы могли добавить оценку в качестве нового свойства внутри своей модели, но у существующих пользователей этого свойства еще нет. Поэтому, когда вы пытаетесь обновить его, нет смысла обновлять.
Хорошо, но когда я добавляю слово, оценка не обновляется. Я посмотрел в console.info. при добавлении слова консоль регистрирует POST локальный: 3000/API/слов 400 (неверный запрос).
Давайте продолжить обсуждение в чате.
что в первую очередь вы хотели бы сделать с помощью этой функции?