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);
CodePudding user response:
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()
and showScores()
functions and implement these changes:
app.post("/newScore", async function(req, res){ //< Mark callback as async
try{ //< Use try/catch to handle any errors you may not be aware of
let newScore = new Scores({
player: req.body.playerName,
score: req.body.score,
time: req.body.time,
sps: (req.body.score/req.body.time).toFixed(2)
});
await newScore.save();
res.status(201).json({ //< You need to return a response
message: 'New Score added'
})
}catch(err){ //< Catch any errors and log them in console
console.log(err)
res.status(500).json({
message: 'Error on server'
})
}
});
app.get("/showScores", async function(req, res){ //< Mark callback as async
try{
const data = await Scores.find({}).sort({_id: -1}).limit(5);
res.status(200).json({ //< You need to return a response
data: data
})
}catch(err){ //< Catch any errors and log them in console
console.log(err)
res.status(500).json({
message: 'Error on server'
})
}
})
CodePudding user response:
I'd recommend you the code that I checked.
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));
}
})
=>
showScores();
async function showScores() {
try {
console.log("showScores server command firing");
const scoreData = await Scores.find().sort(_id).limit(5);
res.json({
data: scoreData
})
} catch (error) {
console.log("showScore error:", error.message);
res.json({
error: error.message
})
}
}
I wonder why you unneeded brackets })
after showScrores()
function's last bracket. It would be cause an unexpected error.