I made a program with a game. The game is supposed to register and display the most recent scores. However, in testing, I’ve discovered a bizarre pattern.
I’ll start the server. The first five times I try to play the game and submit my score, it will always successfully submit the new score to the database. Only about half the time will the scoreboard in the html document update, so submission to the database works perfect every time, retrieval works about half the time. The sixth time I try, the program always breaks. Neither submission nor retrieval works anymore. The values I tried to submit will show up on the scoreboard when I restart the server, but the order is off, the latest score submitted not showing up on top, earlier scores showing up above it.
I thought the fact that it runs five times successfully before breaking might be linked to the "5" in the ".limit(5)", but changing that did not help. Can someone see what’s wrong with this code, why it always breaks on my sixth attempt?
require('dotenv').config();
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const mongoURI = process.env.MONGO_URI;
const bodyParser = require("body-parser");
const cors = require("cors");
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use(express.static(__dirname));
app.use(cors());
mongoose.connect(mongoURI);
//this presents the game page
app.get("/", function(req, res){
res.sendFile(__dirname + "/index.html");
})
app.post("/newScore", function(req, res){
addScore(req.body);
})
const schema = new mongoose.Schema({
player: String,
score: Number,
time: Number,
sps: Number
});
const Scores = mongoose.model("Score", schema);
//this is used to get the scores to the board
app.get("/showScores", function(req, res){
showScores();
async function showScores(){
//let newScores = new Score({player: data.username})
console.log("showScores server command firing");
await Scores.find({}).sort({_id: -1}).limit(5).then((data) => res.json(data));
}
})
//this adds scores to the db
async function addScore(data){
console.log("adding score");
let newScore = new Scores({
player: data.playerName,
score: data.score,
time: data.time,
sps: (data.score/data.time).toFixed(2)
})
await newScore.save();
console.log("new score added")
}
app.listen(3000);
2
Answers
Defining your functions inside your route handlers and then calling them is a bit of an anti-pattern in Node.js. It is better to define your functions in a module (seperate file) and export them. This will allow you to import them where you need them and then execute them. This modular approach allows code sharing throughout projects.
Anyway, to get your application working as expected you need to make a few modifications. You don’t seem to be handling any errors and not always returning a response in the right way so you are getting unexpected behaviour. Delete your
addScore()
andshowScores()
functions and implement these changes:I’d recommend you the code that I checked.
=>
I wonder why you unneeded brackets
})
aftershowScrores()
function’s last bracket. It would be cause an unexpected error.