How do I update multiple collections in a specific way when the user clicks a button?

I have two collections:
test.matchhistories (for storing data of previous matches)
test.userdbs (for storing data of players)

I have a page called “live-tracking.ejs”

Here is the table for the file:

<main id="site-main">
    <div class="container">
        <div class="box-nav d-flex justify-between">
            <a onclick="nextPoint()" id="next" class="border-shadow">
                <span class="text-gradient2">Next Point <i class="fas fa-arrow-right"></i></span>
            </a>
            <a id="advancedB" onclick="showAdvanced(this.id)" class="border-shadow ad">
                <span class="text-gradient2">Advanced Stats <i class="fas fa-eye"></i></span>
            </a>
            
            <a id="currentB" onclick="showCurrent(this.id)" class="border-shadow ad">
                <span class="text-gradient2">Current Game Stats <i class="fas fa-eye"></i></span>
            </a>
            <a href="/game-over" id="GameOver" class="border-shadow">
                <span class="text-gradient2">Game Over <i class="fas fa-check"></i></span>
            </a>
        </div>
        <form id="liveTrackingForm" class="d-flex">
            <table class="table">
                <thead class="thead-dark">
                    <tr class="currentPoint">
                        <th><button type="button" onclick="sortTable(0, 0)" class="btn" id="sortButton0">Name</button></th>
                        <th><button type="button" onclick="sortTable(1, 1)" class="btn" id="sortButton1">Gender</button></th>
                        <th><button type="button" onclick="sortTable(2, 2)" class="btn" id="sortButton2">Position</button></th>
                        <th><button type="button" onclick="sortTable(3, 3)" class="btn" id="sortButton3">Goals</button></th>
                        <th><button type="button" onclick="sortTable(4, 4)" class="btn" id="sortButton4">Assists</button></th>
                        <th><button type="button" onclick="sortTable(5, 5)" class="btn" id="sortButton5">Turnovers</button></th>
                        <th><button type="button" onclick="sortTable(6, 6)" class="btn" id="sortButton6">Blocks</button></th>
                        <th><button type="button" onclick="sortTable(7, 7)" class="btn" id="sortButton7">Playing</button></th>
                    </tr>
                    <tr class="hidden current">
                        <th><button type="button" onclick="sortTable(8, 0)" class="btn" id="sortButton8">Name</button></th>
                        <th><button type="button" onclick="sortTable(9, 1)" class="btn" id="sortButton9">Gender</button></th>
                        <th><button type="button" onclick="sortTable(10, 2)" class="btn" id="sortButton10">Position</button></th>
                        <th><button type="button" onclick="sortTable(11, 3)" class="btn" id="sortButton11">Goals</button></th>
                        <th><button type="button" onclick="sortTable(12, 4)" class="btn" id="sortButton12">Assists</button></th>
                        <th><button type="button" onclick="sortTable(13, 5)" class="btn" id="sortButton13">Turnovers</button></th>
                        <th><button type="button" onclick="sortTable(14, 6)" class="btn" id="sortButton14">Blocks</button></th>
                        <th><button type="button" onclick="sortTable(15, 7)" class="btn" id="sortButton15">Points Played</button></th>
                    </tr>
                    <tr class="hidden advanced">
                        <th><button type="button" onclick="sortTable(16, 0)" class="btn" id="sortButton16">Name</button></th>
                        <th><button type="button" onclick="sortTable(17, 1)" class="btn" id="sortButton17">Gender</button></th>
                        <th><button type="button" onclick="sortTable(18, 2)" class="btn" id="sortButton18">Position</button></th>
                        <th><button type="button" onclick="sortTable(19, 3)" class="btn" id="sortButton19">Goals</button></th>
                        <th><button type="button" onclick="sortTable(20, 4)" class="btn" id="sortButton20">Assists</button></th>
                        <th><button type="button" onclick="sortTable(21, 5)" class="btn" id="sortButton21">Turnovers</button></th>
                        <th><button type="button" onclick="sortTable(22, 6)" class="btn" id="sortButton22">Blocks</button></th>
                        <th><button type="button" onclick="sortTable(23, 7)" class="btn" id="sortButton23">Points Played</button></th>
                    </tr>
                </thead>
                
                <tbody>
                    <% for(var i = 0; i < users.length; i++) { %>
                        <tr class="currentPoint" id="counter">
                            <td><%= users[i].name %></td>
                            <td><%= users[i].gender %></td>
                            <td><%= users[i].position %></td>
                            <td><input type="checkbox" onclick="goal(this)" class="goal" data-name="<%= users[i].name %>"></td>
                            <td><input type="checkbox" onclick="assist(this)" class="assist" data-name="<%= users[i].name %>"></td>

                            <% for(var j = 0; j < 2; j++) { %>
                                <td>
                                    <div>
                                        <button type="button" onclick="increment(this)">+</button>
                                        <span id="countValue_<%= i %>">0</span>
                                        <button type="button" onclick="decrement(this)">-</button>
                                    </div>
                                </td>
                            <% } %>
                            <td><input type="checkbox" onclick="updatePlayingArray(this)"></td> 
                        </tr>
                        <tr class="hidden current">
                            <td><%= users[i].name %></td>
                            <td><%= users[i].gender %></td>
                            <td><%= users[i].position %></td>
                            <td><%= users[i].cGoals %></td>
                            <td><%= users[i].cAssists %></td>
                            <td><%= users[i].cTurnovers %></td>
                            <td><%= users[i].cBlocks %></td>
                            <td><%= users[i].cPointsPlayed %></td>
                        </tr>
                        <tr class="hidden advanced">
                            <td><%= users[i].name %></td>
                            <td><%= users[i].gender %></td>
                            <td><%= users[i].position %></td>
                            <% if (Number.isNaN(users[i].goals/users[i].pointsPlayed)) { %>
                                <td>0</td>
                            <% } else { %>
                                <td><%= parseFloat(users[i].goals/users[i].pointsPlayed).toFixed(2)%></td><% } %>
                            <% if (Number.isNaN(users[i].assists/users[i].pointsPlayed)) { %>
                                <td>0</td>
                            <% } else { %>
                                <td><%= parseFloat(users[i].assists/users[i].pointsPlayed).toFixed(2)%></td><% } %>
                            <% if (Number.isNaN(users[i].turnovers/users[i].pointsPlayed)) { %>
                                <td>0</td>
                            <% } else { %>
                                <td><%= parseFloat(users[i].turnovers/users[i].pointsPlayed).toFixed(2)%></td><% } %>
                            <% if (Number.isNaN(users[i].blocks/users[i].pointsPlayed)) { %>
                                <td>0</td>
                            <% } else { %>
                                <td><%= parseFloat(users[i].blocks/users[i].pointsPlayed).toFixed(2)%></td> <% } %>
                            <td><%= users[i].pointsPlayed %></td>
                        </tr>
                        <% } %>            
                </tbody>
                <thead class="thead">
                    <tr class="hidden advanced miniHeader"><th colspan="9">Per Point Stats</th></tr>
                </thead>
                <thead class="thead">
                    <tr class="hidden current miniHeader"><th colspan="9">Current Game Stats</th></tr>
                </thead>
            </table>
        </form> 
    </div>
</main>

The table I built has counter where the user can update the stats of a specific player in test.userdbs by using increment counters where the X’s are.

Table     Goals     Assists     Turnovers     Blocks

User1       x          x           x             x   

User2       x          x           x             x  

User3       x          x           x             x  


Lets say currently, we are tracking the stats while playing against team1. In test.matchhistory, there will be a document with test.matchhistory.name = “team1”

If User1’s goals’ counter increases, I want to add whatever number the counter has and add it to User1′ existing goals AND cGoals in test.userdbs.

Within this file, I also have setup a 2d array called eventLine. Whenever the user clicks the “next point” button, I want to push this eventLine array to test.matchhistory -> team1 -> eventList (array). Moreover, if there is a “Goal” in the eventLine array, add 1 to matchhistory.ourScore. If not, add 1 to matchhistory.theirScore

here is the model of the collections

import mongoose from 'mongoose';

const matchHistorySchema = new mongoose.Schema({
    team: String,
    win: Boolean,
    ourScore: Number,
    theirScore: Number,
    date: Number,
    od: String,
    location: String,
    eventList: Array
});

const schema = new mongoose.Schema({
    name: String,
    age: String,
    number: String,
    gender: String,
    position: String,
    contact: String,
    status: String,
    note: String,
    assists: Number,
    goals: Number,
    turnovers: Number,
    blocks: Number,
    pointsPlayed: Number,
    cAssists: Number,
    cGoals: Number,
    cTurnovers: Number,
    cBlocks: Number,
    cPointsPlayed: Number
});

const MatchHistory = mongoose.model('MatchHistory', matchHistorySchema);
const Userdb = mongoose.model('userdb', schema);

export { MatchHistory, Userdb };

The variables for the collections used in my live-tracking file is selectedMatch and users

For updating the eventList,
I tried running this function that gets called on when “next point” is pressed

function nextPoint() {
    eventLine.push("point")
    const data = {
        eventLine: eventLine,
    };

    $.ajax({
        url: '/api/updateEventList',
        method: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(data),
        success: function (response) {
            console.log('Success:', response);
            // Reset the eventLine array if needed
            eventLine.length = 0;
            // Reload the page or update as needed
            window.location.reload();
        },
        error: function (error) {
            console.error('Error:', error);
        },
    });
}

Then this
route.put('/api/updateEventList', controller.updateEventList);

And finally


export const updateEventList = async (req, res) => {
    const { eventLine } = req.body;
    
    try {
        // Find the most recent match history entry
        const mostRecentMatch = await MatchHistory.findOne().sort({ date: -1 });

        if (!mostRecentMatch) {
            return res.status(404).json({ message: 'No match history found' });
        }
        if ("point" in eventLine){
            mostRecentMatch.ourScore = mostRecentMatch.ourScore + 1;
        } else {
            mostRecentMatch.theirScore = mostRecentMatch.theirScore+1;
        }

        // Update the eventList with the new data
        mostRecentMatch.eventList.push(eventLine);

        // Save the updated match history
        const updatedMatchHistory = await mostRecentMatch.save();

        res.json({ message: 'Event list updated successfully', matchHistory: updatedMatchHistory });
    } catch (error) {
        console.error(error);
        res.status(500).json({ error: 'Internal server error' });
    }
};

But I am returned with

jquery.min.js:2     POST http://localhost:3000/api/updateEventList 404 (Not Found)
send @ jquery.min.js:2
ajax @ jquery.min.js:2
nextPoint @ live-tracking:403
onclick @ live-tracking:72
live-tracking:416 Error: {readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}abort: ƒ (e)always: ƒ ()catch: ƒ (e)done: ƒ ()fail: ƒ ()getAllResponseHeaders: ƒ ()getResponseHeader: ƒ (e)overrideMimeType: ƒ (e)pipe: ƒ ()progress: ƒ ()promise: ƒ (e)readyState: 4responseText: "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot POST /api/updateEventList</pre>\n</body>\n</html>\n"setRequestHeader: ƒ (e,t)state: ƒ ()status: 404statusCode: ƒ (e)statusText: "Not Found"then: ƒ (t,n,r)[[Prototype]]: Object
error @ live-tracking:416
c @ jquery.min.js:2
fireWith @ jquery.min.js:2
l @ jquery.min.js:2
(anonymous) @ jquery.min.js:2
load (async)
send @ jquery.min.js:2
ajax @ jquery.min.js:2
nextPoint @ live-tracking:403
onclick @ live-tracking:72

I have not tried updating the user stats or matchhistory.their/ourScore.

Obviously it will return 404 because you defined the route with put method but calling in $.ajax as POST method

function nextPoint() {
    eventLine.push("point")
    const data = {
        eventLine: eventLine,
    };

    $.ajax({
        url: '/api/updateEventList',
        method: 'PUT',                 // Change this
        contentType: 'application/json',
        data: JSON.stringify(data),
        success: function (response) {
            console.log('Success:', response);
            // Reset the eventLine array if needed
            eventLine.length = 0;
            // Reload the page or update as needed
            window.location.reload();
        },
        error: function (error) {
            console.error('Error:', error);
        },
    });
}

Leave a Comment