Increment field user.entries when I hit submit - javascript

any idea how to increment a field called 'entries' by 1 every time I hit the submit button and save it to the database (I am using MongoDB/mongoose)?
app.put('/image', (req, res) => {
const { id } = req.body;
User.findByIdAndUpdate(id)
.then(user => {
return res.json(user.entries);
})
.catch(err => {
res.status(400).json('Error getting entries');
console.log(err);
})
});
I tried the auto-incremet plugin, but I don't know if it works in this case, if so I couldn't quite place it in the right place. I also tried to add like
User.findByIdAndUpdate(id, {$inc: {'entries': 1}} but it only starts to work when I hit the but twice and on.
If anyone can help me It'd be a great help!! Thanks

It is working. The only reason is that, findByIdAndUpdate returns the document before actually performing the update operation. If you want to get the increment value after the update operation, You might want to split the findByIdAndUpdate and try
User.update({_id: id},{$inc: {'entries': 1}}).then(() => {
User.findOne({_id: id}).then( user =>{
return res.json(user.entries);
})
}).catch(err => {
res.status(400).json('Error getting entries');
console.log(err);
})
You could also check this solution out by #Jonathan Lonowski if you still want to go with the findByIdAndUpdate.

Related

filled array is empty when send back to user

I try to get data from an azure database with SQL and for this I use tedious. When I execute the code, the array "result" gets filled up with data but when de respond sends the array "result" to the user it is empty. Why and how can I solve it? (I want to send it back in JSON format, the legth is unknown I use 5 to debug).
This is my code
router.get('/', async (req, res) => {
result = []
let rowData = {}
const request = new Request(
`SELECT TOP (5) [LogID]
,[OpdrachtID]
,[ChangeLog]
,[TimeStamp]
,[PersonID]
FROM [log].[LOpdracht]`,
function (err, rowCount, rows) {
if (err) throw err
})
connection.execSql(request)
request.on('row', function(columns){
rowData = {}
columns.forEach(function(column){
rowData[column.metadata.colName] = column.value
})
result.push(rowData)
})
res.send(result)
})
Looks like you are using Tedious. If that is so then you can use the 'done' event to be notified when the request has completed and all rows have been read into result.
request.on('done', () => res.send(result));
Update: As the note in the documentation points out, since you are using execSql you will need to listen to doneProc and doneInProc instead:
request.on('doneProc', () => res.send(result));
request.on('doneInProc', () => res.send(result));
I solved it by adding this:
request.on('requestCompleted', () => {
res.send(result)
})

Axios Post is not completing every time

Iam new to React and I got some problems.
This is my current API call.
Axios.post(Addr_currentRound_addOne, { gameId: gameId }).then(history.push("/leiter_tunierplan/"+gameId));
And this is the corresponding API Code snippet.
app.post("/currentRoundAddOne", (req, res) => {
const gameId = req.body.gameId;
db.query(
"UPDATE tunierplan SET currentRound=currentRound+1 WHERE id=?;",
[gameId],
(err, result) => {
if (err) {
console.log(err);
} else {
res.send("Daten Übertragen");
}
}
);
});
The problem here:
currentRound, should allways when the call is executed increased by +1.
And then Redirect to the given "/leiter_tunierplan/"
BUT
From time to time, it does not work. Its not increasing it by any Value (+1)
My first thought is: Because its async it my be canceled from the history.push, befor it got completed. Am i right? And how can i fix it.
Thanks allready.
Is game gameId the already incremented id for the next page? I don't see it being incremented anywhere in your code.
If so, try putting history.push in a callback, like this:
...then(() => history.push("/leiter_tunierplan/"+gameId));
This is because then takes a callback function as a parameter
The Solution to all is to add preventDefault();
My Problem was, that the side got reloaded..
I think you try async-await as the request to the database is promise-based.
My suggestion:
app.post("/currentRoundAddOne", async (req, res) => {
const gameId = req.body.gameId
const data = await db.query("UPDATE tunierplan SET currentRound=currentRound+1 WHERE id=?;", [gameId],
(err, result) => {
if (err) console.log(err);
}
console.log(data) // check updated data, it should return id
})
I hope it works!

PreventDefault inside of promise in React

I'm new to full stack development and I was looking for some pointers to how I can handle errors that return from a promise.
Basically, I have Game IDs stored in a MongoDB collection. When a user enters a Game ID, I want to check if the Game ID exists in the collection. If it doesn't, I don't want to link the user to a new page. If it does, the user should go to a new page.
Currently, my code doesn't prevent default and the user still goes to the "waitpage", even if I use event.preventDefault. I'm wondering how I can stop the user from going to this page.
This is the code I have right now in the frontend.
const onJoinGame = (event) => {
event.persist()
axios.get(`${BACKENDLINK}/rooms/${gameId}/room_available`)
.then((res) => {
if(res.data.Status == true){
axios.put(`${BACKENDLINK}/rooms/${gameId}/add_user`,
{
username: username
})
}
})
.catch((error) => {
event.preventDefault()
setErrorGameId("That game doesn't exist!")
})
}
And in the return statement, I use this function like so.
<Link to={`/${gameId}/waitpage`} onClick={(event) => onJoinGame(event)}>
<button className = "submit" id="joinGame">Join Game</button>
</Link>
In the backend, this is what my get function returns.
const roomAvailable = (req, res) => {
Room.findOne({roomId: req.params.id}, (err, result) =>{
if(!result){
res.status(400).json('Error: ' + err)
}
else{
res.json({'Status': true})
}
})
}
Any help would be greatly appreciated!
You can't prevent the event from a promise, you'll need to do that synchronously in the event handler.
If you do need to navigate to the other page after all, you'll have to do that manually using the imperative API of the router package (which provides Link) you're using.

'TypeError: Converting circular structure to JSON' with Express

I use NodeJS and Express for my project and set it when the user login to index will keep the session value.
req.session.user
{ adminID: 3, username: 'admin', password: 'admin' }
And I want to get data from MYSQL so I use Knex like this.
router.get('/profile/user/me', (req, res, next) => {
let user = req.session.user;
if(user) {
try {
let me = req.session.user.adminID;
let info = knex('admin_account').where('adminID', `%${me}%`)
res.json(info)
} catch (e) {
console.log(e);
}
res.sendFile(path.join(__dirname + '/../public/personal_information.html'));
return;
}else{
res.redirect('/');
}
});
In my opinion, I think that if we are finished logging in, we will have a req.session.user I will use it to get data together with Knex.
req.sessions.user and info may have the same value but arent the same type you should, first check the value of your variable info console.log(info), there is a chance that you might need to json.parse() it or json.stringify() it if you want to send it as a response.
You need to execute the query builder and wait for result before returning:
knex('admin_account').where('adminID', me)
.then(info => {
res.json(info)
})
.catch(err => {
console.log(e);
});
And you don't need % wildcards unless you are doing loose string comparison with like operator.
One more thing about the code is that you seem to try to return res.json and also res.sendFile(path.join(__dirname + '/../public/personal_information.html')) at the same time, which doesn't make sense.

User not updating in mongo after save?

I have an app for todos. I'm trying to update a specific todo within an array of todos stored in the User I'm currently logged into. This is the code that does that:
User.findById(req.user._id)
.then(user => {
user.todos.forEach(function(todo) {
if (todo._id == req.params.todoId) {
todo.completed = !todo.completed;
console.log(todo.completed);
}
})
return user.save();
})
.then(result => {
console.log(result);
res.json(result);
})
.catch(function(err) {
res.send(err);
})
When I console.log the result, everything comes out fine. When I console log the updated Todo in the ajax call I'm making in my javascript file, everything appears fine. The todo is updated. However, when I stop my server and find the user in Mongo, the todo still isn't updated.
Any help is much appreciated.
When you modify a nested property on a document, mongoose may not be aware that anything changed, so it won't know to persist the changes in the DB (otherwise it would have to pass everything, which could become expensive if you have a large document but only a tiny part of it changed).
This can be done via the markModified method:
user.todos.forEach(function(todo) {
if (todo._id == req.params.todoId) {
todo.completed = !todo.completed;
console.log(todo.completed);
}
})
user.markModified('todos');
return user.save();
Instead of doing it in JavaScript code I will suggest you can do it in query only which will more effective.
db.getCollection('User').update({"_id":<req.user._id>,"todo._id":<req.params.todoId>},
{$set:
{'todo.$.completed': true}
}, {
new : true
}
)
In this query you need to pass completed status as well.

Categories

Resources