问题
My app has two Models. User and Tournament. User model has username
and _id
(mongodb).
Tournament model has participants
which is an Array.
I'm trying to make it so each and every user who signs up to a tournament can do so only once.
I wrote an Express route to POST to a tournament's participants
array:
router.post('/:id', (req, res) => {
Tournament.findById(req.params.id)
.then(tournament => {
const userSignedUp = (participantsArray, user) => {
return participantsArray.some(arr => arr.user === user);
};
// Check if User already signed up
if (userSignedUp(tournament.participants, req.body.user._id) !== true && userSignedUp(tournament.participants, req.body.user.id) !== true) {
tournament.participants.push(req.body.user);
} else {
return res.status(400).json({ msg: "This user is already signed up" });
}
return tournament.save();
})
.then(savedTournament => res.json(savedTournament))
.catch(err => res.json(err));
});
After some experimentation I learned how to write that if()
statement to prevent the User from signing up more than once:
Then I did my best to wire up Redux to send what I want to that route, via axios
REDUCER:
const initialState = {
participant: null
};
export default function(state = initialState, action) {
switch(action.type) {
case USER_JOINS_TOURNAMENT:
return {
...state,
participant: action.payload
}
case TOURNAMENT_SIGN_UP_FAIL:
return {
...state,
participant: null
}
default:
return state;
};
};
ACTION:
export const addParticipant = (_id, user) => dispatch => {
const config = {
headers: {
"Content-Type": "application/json"
}
};
const body = JSON.stringify({ user });
axios.post(`/tournaments/${_id}`, body, config)
.then(() => dispatch({
type: USER_JOINS_TOURNAMENT,
payload: user
}))
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status));
dispatch({
type: TOURNAMENT_SIGN_UP_FAIL
});
});
};
I wasn't sure if I needed config//body there, but it didn't work right without that.
With this in place, a User can log in, create a Tournament, and then Sign up once. If he signs up again, it'll block him with an error message.
However, when I log onto another User, it gives the same error message (even though the tournament.participants
array doesn't have that user's ID in it)
AND in my terminal I get this error:
(node:9734) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
[0] at ServerResponse.setHeader (_http_outgoing.js:526:11)
[0] at ServerResponse.header (/home/dustin/Desktop/Smash-Hosting/node_modules/express/lib/response.js:771:10)
[0] at ServerResponse.send (/home/dustin/Desktop/Smash-Hosting/node_modules/express/lib/response.js:170:12)
[0] at ServerResponse.json (/home/dustin/Desktop/Smash-Hosting/node_modules/express/lib/response.js:267:15)
[0] at /home/dustin/Desktop/Smash-Hosting/routes/api/tournaments.js:109:21
[0] at processTicksAndRejections (internal/process/task_queues.js:97:5)
[0] (node:9734) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
[0] (node:9734) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I'm not really sure where to start. I read some docs/solutions to that error message but I didn't see something that stands out to me. Perhaps I coded myself into a corner. I hope this all makes sense.
来源:https://stackoverflow.com/questions/61351906/mern-added-a-user-object-to-another-models-array-prevented-duplicate-addition