MongoDB, Nodejs routing order - mongodb

I have the problem with my routes. They work but only the one that's in the code first. The code below allows me to get a ticket by ID but not by registration number. If I put the second route above the first one it's vice versa.
What can I do to fix this?
//Get a ticket by ID
app.get('/tickets/:_id', function(req, res){
Ticket.getTicketById(req.params._id, function(err, ticket){
if(err){
throw err;
}
res.json(ticket);
});
});
//Get a ticket by registration number
app.get('/tickets/:vehRegistration', function(req, res){
Ticket.getTicketByReg(req.params.vehRegistration, function(err, ticket){
if(err){
throw err;
}
res.json(ticket);
});
});

You have written the same API path twice. :param_name can't be used to differentiate between two different paths. Try
//Get a ticket by ID
app.get('/tickets/byid/:_id', function(req, res) {
Ticket.getTicketById(req.params._id, function(err, ticket) {
if (err) {
throw err;
}
res.json(ticket);
});
});
//Get a ticket by registration number
app.get('/tickets/byreg/:vehRegistration', function(req, res) {
Ticket.getTicketByReg(req.params.vehRegistration, function(err, ticket) {
if (err) {
throw err;
}
res.json(ticket);
});
});

Related

Router-level middleware order using Express.js

I have the following routers:
/* GET /users/username */
router.get("/:username", function(req, res, next) {
User.findOne({
username: req.params.username
}).exec(function(err, user) {
if (err) return next(error);
res.json(user);
});
});
/* GET /users/id */
router.get("/:id", function(req, res, next) {
User.findById(req.params.id, function(err, user) {
if (err) return next(err);
res.json(user);
});
});
In the above order, /* GET /users/id */ will return null, and if I swap the order the /* GET /users/username */ will result in this error:
Cast to ObjectId failed for value "Guest" at path "_id" for model "User"
Basically, the second middleware is being ignored. However, both are needed for different behaviors. I'm using AngularJS $resource to interact with RESTful server-side data sources.
Why can't I use both simultaneously? Why is the second middleware ignored?
In which order should these two routers be to both working?
The second middleware is ignored, because the url pattern is the same... How do you want the router make the differenciation between an 'username' or an 'id';
You've got to check if it's an id first per exemple.
router.get("/:username", function(req, res, next) {
const username = req.params.username;
if (!isNaN(parseInt(username)) { // <------ Check if it's an ID
next();
} else {
User.findOne({
username: req.params.username
}).exec(function(err, user) {
if (err) return next(error);
res.json(user);
});
}
});
/* GET /users/id */
router.get("/:id", function(req, res, next) {
User.findById(req.params.id, function(err, user) {
if (err) return next(err);
res.json(user);
});
});
It's better to route by doing:
router.route('your/route').get(aJsFile.function);
Then, instead of the exec, just write
attributes: ['id', 'username']
where: {username: username}
Or something like this.

Mongo db connection not establishing

Below is the code which i used to up the server. It is running in the localhost server 3000.
app.use('/', books);
app.listen(3000, function(){
console.log('Server running at port 3000: http://localhost:3000')
});
Below code throws mongodb error. Dont know what exactly the error. Below is my code
var express = require('express');
var router = express.Router();
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://127.0.0.1:27017';
// SHOW LIST OF BOOKS
router.get('/book', function(req, res, next) {
MongoClient.connect(url, function(error, db) {
if (error) throw error;
var dbo = db.db("BookStore");
dbo.collection("Books").find().toArray(function(err, result) {
if (err) throw err;
res.send(result);
console.log(result);
db.close();
});
});
});
// SHOW BOOK with ISBN
router.get('/book/:isbn', function(req, res, next) {
var isbn = parseInt(req.params.isbn);
MongoClient.connect(url, function(error, db) {
if (error) throw error;
var dbo = db.db("BookStore");
var query = { "isbn": isbn };
dbo.collection("Books").findOne(query, function(err, result) {
if (err) throw err;
res.send(result);
console.log(result);
db.close();
});
});
});
// Add BOOK
router.post('/book', function(req, res, next) {
MongoClient.connect(url, function(error, db) {
if (error) throw error;
var dbo = db.db("BookStore");
var myobj = {
"isbn":req.body.isbn,
"publisher":req.body.publisher,
"title":req.body.title,
"authors":req.body.authors,
"publishedDate":req.body.publishedDate,
"price":req.body.price
};
dbo.collection("Books").insertOne(myobj, function(err, result) {
if (err) throw err;
res.send('Book with '+req.body.isbn+' is successfully added');
db.close();
});
});
});
// UPDATE BOOK
router.put('/book/:isbn', function(req, res, next) {
var isbn = parseInt(req.params.isbn);
MongoClient.connect(url, function(error, db) {
if (error) throw error;
var dbo = db.db("BookStore");
var query = { "isbn": isbn };
var newvalues = { $set: {
"publisher":req.body.publisher,
"title":req.body.title,
"authors":req.body.authors,
"publishedDate":req.body.publishedDate,
"price":req.body.price
}
};
dbo.collection("Books").updateOne(query, newvalues, function(err, result) {
if (err) throw err;
res.send('Book with '+req.params.isbn+' is successfully updated');
db.close();
});
});
});
// DELETE BOOK
router.delete('/book/:isbn', function(req, res, next) {
var isbn = parseInt(req.params.isbn);
MongoClient.connect(url, function(error, db) {
if (error) throw error;
var dbo = db.db("BookStore");
var query = { "isbn": isbn };
dbo.collection("Books").deleteMany(query, function(err, result) {
if (err) throw err;
res.send('Book with '+req.params.isbn+' is successfully removed');
db.close();
});
});
});
module.exports = router;
Code Explanation:
We are creating a route to our application called 'Books.' So
whenever anybody browses to http://localhost:3000/books of our application, the code snippet defined for this route will be
executed.
Here we are getting all of the records in our 'Books'
collection through the db.collection('Books').find() command. We are then assigning this collection to a variable called cursor. Using this cursor variable, we will be able to browse through all of the records of the collection.
Run sudo mongod in the terminal
Is it impossible to connect even if you change the value assigned to the variable url to mongodb://[user_name]:[password]#127.0.0.1:27017/[your_database_name]?authSource=admin ?
Actually, the error is related to MongoDB version(MongoClient.connect(url, function(error, db)), MongoDB developers have changed their API. I don't know which version, it throws an error when you use MongoClient.connect(url, function(error, db).
So it should be MongoClient.connect(url, function(err, client)
Link to api-doc
And do not forget to run mongod

node-postgresql db connection deprecated

I am using node-v8.9.1-x64. & postgresql-10.1-2. I have tried running this code but its gives an error "code deprecated" and even tried some other ways. It still comes back with new errors
app.get('/', function(req, res) {
// PG connect -code deprecated
pg.connect(connect, function(err, client, done) {
if(err) {
return console.error('error fetching client from pool', err);
}
client.query('SELECT * FROM books', function(err, result) {
if(err) {
return console.error('error running query', err);
}
res.render('index', {books: result.rows});
done();
});
});
I went through the documentation but I am not getting it. Please somebody help me.

removing multiple document's references using mongoose

I'm currently trying to remove multiple documents references (objectId) when i'm removing those documents.
So this is my code to remove multiple documents and their references:
Comment.find({parentCommentId: req.params.id}).stream()
.on('data', function (comment) {
comment.remove(function (err, result) {
if (err){
console.log(err)
}
console.log(result);
})
})
.on('error', function(err){
// handle error
})
.on('end', function(){
res.status(200).json({
title: 'Comments deleted'
});
});
(this is the middleware i use)
schema.post('remove', function (comment) {
Project.findById(comment.project, function (err, project) {
if(err){
console.log('error : '+ err)
}
project.comments.pull(comment);
project.save();
});
User.findById(comment.user, function (err, user) {
if(err){
console.log('error : '+ err)
}
user.comments.pull(comment);
user.save();
});
});
At the moment i tried multiple things but i kinda got stuck: it removes all the documents i wanted but it always only removes the first document's reference and keeps the other ones.
at this point i don't really understand why.
Have a good day : )

Node Express Trouble returning object to view from query

I'm trying to:
Pass user's ID to a model query, that should return the user record from mongo.
Render this user object to my view so I can use its fields.
I'm not quite sure what's going wrong - the query function finds the correct user and I can console.dir to see all the fields. When I try to return it to my view with res.render I get nothing:
Here's my route:
app.get('/account', function(req, res) {
res.render('account', {title: 'Your Account', username: req.user.name, user:account.check(req.user.id) });
});
And my query function:
exports.check = function(userId) {
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err) throw err;
var collection = db.collection('test');
collection.findOne({userId : userId}, function(err, user) {
if (err) throw err;
console.log("account.check logging found user to console: ");
console.dir(user);
return user;
});
});
}
Again, this shows the proper entry
Finally my view:
<h1>Account Page</h1>
<hr>
<p>Why, Hello, there <b> {{username}} </b> </p><br/>
<p>You came from {{user.provider}}</p>
<p>{{user.lastConnected}}</p>
Go Home ~ Log Out
Any held would be most appreciated!
The MongoDB findOne function is asynchronous (it takes a callback as an argument). This means that your check function also needs to be asynchronous and take a callback as an argument (or return a promise).
Then you should call res.render() inside the callback you pass to query on success.
app.get('/account', function(req, res) {
account.check(req.user.id, function(error, user) {
if (error) {
// do something smart like res.status(500).end()
return;
}
res.render('account', {title: 'Your Account', username: req.user.name, user:user });
}
});
And the check function should be something like:
exports.check = function(userId, callback) {
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err) {
callback(err);
}
var collection = db.collection('test');
collection.findOne({userId : userId}, function(err, user) {
if(err) {
callback(err);
}
console.log("account.check logging found user to console: ");
console.dir(user);
callback(null, user);
});
});
}
Of course if you don't need to do any additional processing, you can just pass your the callback argument as the callback to collection.findOne(). I just kept it this way because it was closer to what you were doing initially.