How to update record in mongoose with nodejs? - javascript

I am trying to update a record in mlab, a remote mongodb database. I am using express, mongoose and nodejs to update a certain record. I also use promises to avoid the callback pyramid.
Api file:
router.put('/chairs/:id', function(req, res, next){
Chair.findByIdAndUpdate({id:req.params.id}, req.body)
.then(function() {
Chair.findOne({id:req.params.id})
})
.then(function(chair){
res.send(chair);
})
.catch(next);
});
I tested the code above using Postman 'x-www-form-urlencoded'. When i try to UPDATE just 1 field 'title' and send PUT REQUEST , I am prompted with
{
"myError": "Cast to ObjectId failed for value \"{ id: '5953532df36d28458af5609f' }\" at path \"_id\" for model \"chair\""
}
I want to update a record and get the ID again and print the updated record.
Please help. I am not sure how to properly nest my promises

Related

TypeError: Cannot read property '0' of undefined in post method in nodejs

I am new to nodejs and mongodb.
I am trying to create simple to-do app with nodejs and mongodb.
I have added the task in database.
Now in post method, I am using insertOne method of mongodb and in res.json I am having the following error.
res.json(info.ops[0].data)
TypeError: Cannot read property '0' of undefined
Code :
app.post('/create-item', function(req, res){
db.collection('items').insertOne({ text:req.body.text }, function(err, info){
res.json(info.ops[0])
})
})
Below is the screenshot of Error.
In current versions, there is no property returned named ops when insertOne is successful.
Hence the error TypeError: Cannot read property '0' of undefined
insertOne returns two properties:
acknowledged
Indicates whether this write result was acknowledged. If not, then all other members of this result will be undefined
insertedId
The identifier that was inserted. If the server generated the identifier, this value will be null as the driver does not have access to that data
See:
InsertOne
InsertOneResult
app.post('/create-item', function(req, res){
db.collection('items').insertOne({ text:req.body.text }, function(err, info){
console.log(info.acknowledged)
console.log(info.acknowledged)
res.json(info.acknowledged)
})
})
In previous versions, for example 3.2, different properties were returned for insertOne:
insertOne #3.2
insertOneWriteOpCallback #3.2
Similarly, different properties were returned for updateOne:
updateOne #3.2
updateOneWriteOpCallback #3.2
For more information about migrating to version 4 from earlier versions, see the article:
Changes in 4.x (and how to migrate!)
I encountered the same problem with the to-do app tutorial today. For those interested try changing the line - res.json(info.ops[0])
to - res.json({ _id: info.insertedId.toString(), text: req.body.text })
This gets the inserted id from the database for the newly added item. As "info" doesn't seem to return the inserted text in the current version of mongodb - i added that from the request parameter.
I got my information from here - Get the _id of inserted document in Mongo database in NodeJS
you are doing it wrong way firstly check the err then send the res.json because the error is because your info might be null if data not inserted successfully so you need to do it like
app.post('/create-item', function(req, res){
db.collection('items').insertOne({ text:req.body.text }, function(err, info){
if (err) {
res.json({message: "not inserted successFully"});
return;
}
res.json(info.ops[0])
})
})
now in above code what will happen if data is not inserted successfully it will send the error as response and return from function.

Why deleteOne & findById of mongoose work on deleted id

Currently developing an API with nodejs that communicates with a MongoDB database, I noticed a special behavior after deleting a document.
Indeed, my API has several endpoints that allow to retrieve all the animals in the database, to retrieve a specific one using the corresponding id or to delete a specific one, again using the id of the document to delete.
The results I don't understand happen once a document is deleted. Indeed, as you can see in the picture below, when I delete the document of the animal called "Johnny" the queries to find it via its id or to delete it via the same ID continue to work, even if the get returns nothing and the deletion indicates that no operation has been performed.
Personally I expected the same behavior as if I passed a wrong id for a deletion (visible below), but if the id has already been assigned in the database the queries work even after a deletion.
Does MongoDB have a "cache" of deleted documents in order to perform a rollback in case of unwanted deletion?
You will find below the different endpoints that use find, deleteOne & findById
exports.getAllAnimal = (req, res, next) => {
Animal.find().sort({'customer' : 1})
.then(animals => res.status(200).send(animals))
.catch(error => res.status(400).send({ error: error.message }));
};
exports.getOneAnimal = (req, res, next) => {
Animal.findOne({ _id: req.params.id })
.then(animal => res.status(200).send(animal))
.catch(error => res.status(400).send({ error: error.message }));
};
exports.deleteAnimal = (req, res, next) => {
Animal.deleteOne({ _id: req.params.id })
.then(thing => res.status(200).send({ message : 'Animal successfully deleted'}))
.catch(error => res.status(400).send({ error: error.message }));
};
MongoDB does not cache deleted id anywhere.
The thing is that when you said I passed a wrong id for a deletion ... you are passing an id with the same length but not in the required format. That's why Mongoose is throwing you an error.
However, if you follow the id structure of MongoDB to create an id that does not exist in the database and run an operation against it, MongoDB will still return you with success and an empty result.
Try using 5ea08034385a46666b05020f and run the .findById() query function against it. It's going to return you with a success an empty result.
The success only means that the operation is successful, but it doesn't necessarily mean that it actually finds something in the database.
I don't have access to your database, so the id is generated randomly but following the MongoDB ObjectId rules below:
The 12-byte ObjectId value consists of:
a 4-byte timestamp value, representing the ObjectId’s creation, measured in
seconds since the Unix epoch
a 5-byte random value
a 3-byte incrementing counter, initialized to a random value
Generate arbitrary MongoDB ObjectId:
https://observablehq.com/#hugodf/mongodb-objectid-generator

How to message client when afterCreate database hook process is ready?

I have an express with sequelize (using postgres) REST backend server. When I post a create request from my client the database entry is created then a afterCreate hook is running a processing script for a second or so. This is running fine using the afterCreate hook form sequelize.
Subsequently I need to let the client know the processing is ready, upon which the client will run some process of its own. How do I message to the client?
I'm not a Node expert and my answer might be wrong, but based on the https://groundberry.github.io/development/2016/11/06/continue-building-your-node-app-with-express-and-sequelize.html couldn't you do the following:
router.post('/', function(req, res) {
//node return reply after running the create
return models.User.create({ username: req.body.username }).then(function() {
return res.json({ message: 'New user created' });
});
});

Query a MongoDB Server Using Express (Node.js project)

I've created a route in a Node.js project to render all "logs" from a MongoDB database to a Web page:
app.get('/api/logs', function (req, res) {
Log.find( function (err, logs) {
res.json(logs);
});
});
I want to modify this query to (1) limit the response to 10 logs and (2) display the logs in reverse chronological order (from most recent to least recent). If I try the below code, nothing will render to my page and my Node server gives the following error: Error: sort() only takes 1 Argument.
app.get('/api/logs', function (req, res) {
Log.find().limit(10).sort({$natural:-1}, function(err, logs){
res.json(logs);
});
});
The above snippet DOES work if I type it directly into my Monog console as a single query: Log.find().limit(10).sort({$natural:-1}) Is there a different way to write this to grab the information I want? Thanks for your suggestions!
This works perfectly:
app.get('/api/logs', function (req, res) {
Log.find().limit(10).sort(-fieldToSort).exec(function(err, logs){
res.send(logs)
})
});
The -fieldToSort sorts the field in a descending order as you requested. fieldToSort is the field name you want to sort.
Hope it helps!

Node.js and SQLite3

I am want to create web server that will return data for my mobile app. I use Node.js for server and SQLite3 for database. I created method that must return data from sql, but I don't know how to do it correctly. As I know all methods from SQLite lib are async so I have no idea how to do sync request for DB. I tried this way:
app.get('/getAllLeagues',function (req, res) {
console.log("get")
var obj = db.all("SELECT name FROM Leagues")
})
But seems that obj is still the same as db object
I'm assuming that your app is an express server instance or similar. The database query function takes a callback function that is called once the queried rows are ready or an error is found.
app.get('/getAllLeagues',function (req, res) {
console.log("get")
var obj = db.all("SELECT name FROM Leagues",
function(err, rows) {
res.type('json');
res.send(rows);
});
});
For simplicity, there is no error handling. It is better to try..catch a similar request to avoid crashing your app in case the database or the table is not found.

Categories