Reupdate the database will not roll back the previous database state

Reupdate the database will not roll back the previous database state
reactjs
Ethan Jackson

I've got this code for updating the match which will also update the other 3 models player team and tournament the code goes like this

const updateMatch = async (req, res) => { try { const { matchId, team1Players, team2Players } = req.body; const match = await MatchModel.findById(matchId); if (!match) { return res.status(404).json({ message: 'Match not found' }); } // Backup old values const previousPlayerStats = {}; match.player_stats.forEach((stat) => { previousPlayerStats[stat.player_id] = { points: stat.points, assists: stat.assists, rebounds: stat.rebounds, }; }); const previousTeam1Points = match.team_1_total_points || 0; const previousTeam2Points = match.team_2_total_points || 0; const previousWinner = match.winner; // REVERSE old player stats for (const stat of match.player_stats) { const player = await PlayerModel.findById(stat.player_id); if (player) { player.total_points -= stat.points; player.total_assists -= stat.assists; player.total_rebounds -= stat.rebounds; await player.save(); } } // APPLY new player stats const applyNewStats = async (players) => { for (const player of players) { const playerDoc = await PlayerModel.findById(player.playerId); if (playerDoc) { playerDoc.total_points += player.points; playerDoc.total_assists += player.assists; playerDoc.total_rebounds += player.rebounds; await playerDoc.save(); } } }; await applyNewStats(team1Players); await applyNewStats(team2Players); // Update match.player_stats match.player_stats = [ ...team1Players.map((p) => ({ player_id: p.playerId, team_id: match.team_1, points: p.points, assists: p.assists, rebounds: p.rebounds, })), ...team2Players.map((p) => ({ player_id: p.playerId, team_id: match.team_2, points: p.points, assists: p.assists, rebounds: p.rebounds, })), ]; // Calculate new totals const team1TotalPoints = team1Players.reduce((sum, p) => sum + p.points, 0); const team2TotalPoints = team2Players.reduce((sum, p) => sum + p.points, 0); let newWinner = null; if (team1TotalPoints > team2TotalPoints) newWinner = match.team_1; else if (team2TotalPoints > team1TotalPoints) newWinner = match.team_2; // Update teams const updateTeam = async (teamId, isNewWinner, oldPoints, newPoints, wasPreviousWinner) => { const team = await TeamModel.findById(teamId); if (team) { team.team_details.total_points_scored -= oldPoints; team.team_details.total_points_scored += newPoints; // Adjust win/loss if changed if (wasPreviousWinner && !isNewWinner) { team.team_details.matches_won -= 1; team.team_details.matches_lost += 1; } else if (!wasPreviousWinner && isNewWinner) { team.team_details.matches_won += 1; team.team_details.matches_lost -= 1; } await team.save(); } }; await updateTeam(match.team_1, newWinner === match.team_1, previousTeam1Points, team1TotalPoints, previousWinner === match.team_1); await updateTeam(match.team_2, newWinner === match.team_2, previousTeam2Points, team2TotalPoints, previousWinner === match.team_2); match.team_1_total_points = team1TotalPoints; match.team_2_total_points = team2TotalPoints; match.winner = newWinner; await match.save(); res.status(200).json({ message: 'Match updated successfully', match }); } catch (error) { console.log(error); res.status(500).json({ message: error.message }); } };

the problem araises when I make a mistake in updating Suppose I put 19 instead of 10, which will increment 19 in all models and I again reupdate with correct value which is 10 which will again reincrement eventually making 29 instead of 10 So, I want to rollback the database to previous state and match is being rollback but not players, tournament and team Can you please suggest me a better approach or any update on the code. Feel free to ask for other code The frontend Code goes like this

import axios from 'axios'; const UpdateMatch = ({ match, onClose }) => { const [updatedTeam1Players, setUpdatedTeam1Players] = useState([]); const [updatedTeam2Players, setUpdatedTeam2Players] = useState([]); useEffect(() => { console.log('Received match details:', match); // Initialize the updated state with the player's stats from playerStats setUpdatedTeam1Players( match.team1Players.map((player) => { const playerStats = match.playerStats.find( (stats) => stats.player_id === player._id && stats.team_id === match.team1Id ); return { playerId: player._id, name: player.name, points: playerStats ? playerStats.points : 0, assists: playerStats ? playerStats.assists : 0, rebounds: playerStats ? playerStats.rebounds : 0, }; }) ); setUpdatedTeam2Players( match.team2Players.map((player) => { const playerStats = match.playerStats.find( (stats) => stats.player_id === player._id && stats.team_id === match.team2Id ); return { playerId: player._id, name: player.name, points: playerStats ? playerStats.points : 0, assists: playerStats ? playerStats.assists : 0, rebounds: playerStats ? playerStats.rebounds : 0, }; }) ); }, [match]); const handleInputChange = (team, playerId, field, value) => { const updatePlayer = (players) => players.map((player) => player.playerId === playerId ? { ...player, [field]: parseInt(value, 10) || 0 } : player ); if (team === 'team1') { setUpdatedTeam1Players(updatePlayer(updatedTeam1Players)); } else { setUpdatedTeam2Players(updatePlayer(updatedTeam2Players)); } }; const handleUpdateMatch = () => { const updatedMatchDetails = { matchId: match.matchId, team1Players: updatedTeam1Players.map((player) => ({ playerId: player.playerId, points: player.points, assists: player.assists, rebounds: player.rebounds, })), team2Players: updatedTeam2Players.map((player) => ({ playerId: player.playerId, points: player.points, assists: player.assists, rebounds: player.rebounds, })), }; console.log('Updated Match Details:', updatedMatchDetails); // Call API to update match details axios .post('http://localhost:8000/api/match/match/update', updatedMatchDetails) .then((response) => { console.log('Match updated successfully:', response.data); if (response.status === 200) { alert('Match updated successfully'); } else { alert('Match not updated successfully'); } }) .catch((error) => { console.error('Error updating match:', error); }); }; return ( <div className="p-4"> <h2 className="text-xl font-bold mb-4">Update Match</h2> <div className="mb-4"> <h3 className="text-lg font-semibold">Tournament: {match.tournamentName}</h3> </div> <div className="flex justify-between mb-4"> <div> <h4 className="text-md font-semibold">Team 1: {match.team1Name}</h4> <table className="min-w-full bg-white border border-gray-300 mt-2"> <thead> <tr className="bg-gray-100"> <th className="py-2 px-4 text-left border-b border-gray-300">Player's Name</th> <th className="py-2 px-4 text-left border-b border-gray-300">Points</th> <th className="py-2 px-4 text-left border-b border-gray-300">Assists</th> <th className="py-2 px-4 text-left border-b border-gray-300">Rebounds</th> </tr> </thead> <tbody> {updatedTeam1Players.map((player) => ( <tr key={player.playerId} className="hover:bg-gray-50"> <td className="border px-4 py-2 text-left">{player.name}</td> <td className="border px-4 py-2 text-left"> <input type="number" value={player.points} onChange={(e) => handleInputChange('team1', player.playerId, 'points', e.target.value) } className="w-full p-1 border border-gray-300 rounded" /> </td> <td className="border px-4 py-2 text-left"> <input type="number" value={player.assists} onChange={(e) => handleInputChange('team1', player.playerId, 'assists', e.target.value) } className="w-full p-1 border border-gray-300 rounded" /> </td> <td className="border px-4 py-2 text-left"> <input type="number" value={player.rebounds} onChange={(e) => handleInputChange('team1', player.playerId, 'rebounds', e.target.value) } className="w-full p-1 border border-gray-300 rounded" /> </td> </tr> ))} </tbody> </table> </div> <div> <h4 className="text-md font-semibold">Team 2: {match.team2Name}</h4> <table className="min-w-full bg-white border border-gray-300 mt-2"> <thead> <tr className="bg-gray-100"> <th className="py-2 px-4 text-left border-b border-gray-300">Player's Name</th> <th className="py-2 px-4 text-left border-b border-gray-300">Points</th> <th className="py-2 px-4 text-left border-b border-gray-300">Assists</th> <th className="py-2 px-4 text-left border-b border-gray-300">Rebounds</th> </tr> </thead> <tbody> {updatedTeam2Players.map((player) => ( <tr key={player.playerId} className="hover:bg-gray-50"> <td className="border px-4 py-2 text-left">{player.name}</td> <td className="border px-4 py-2 text-left"> <input type="number" value={player.points} onChange={(e) => handleInputChange('team2', player.playerId, 'points', e.target.value) } className="w-full p-1 border border-gray-300 rounded" /> </td> <td className="border px-4 py-2 text-left"> <input type="number" value={player.assists} onChange={(e) => handleInputChange('team2', player.playerId, 'assists', e.target.value) } className="w-full p-1 border border-gray-300 rounded" /> </td> <td className="border px-4 py-2 text-left"> <input type="number" value={player.rebounds} onChange={(e) => handleInputChange('team2', player.playerId, 'rebounds', e.target.value) } className="w-full p-1 border border-gray-300 rounded" /> </td> </tr> ))} </tbody> </table> </div> </div> <div className="flex justify-between mt-4"> <button type="button" onClick={onClose} className="bg-red-500 text-white px-4 py-2 rounded" > Close </button> <button type="button" className="bg-blue-500 text-white px-4 py-2 rounded" onClick={handleUpdateMatch} > Update Match </button> </div> </div> ); }; export default UpdateMatch;

Answer

Made simple adjustments that is the input can be negative value and user have to input the value accordingly increment or deceremnt Not the best and scaleabel approach but does the work Can you guyz please suggest me a better one please

Related Articles