Express JS routing based on the user names - mongodb

I am working on a express js project.I have got all my basic routing set up working perfectly. Usually when I want to search a record based on id I do this:
router.route('/sensors_home/:sensor_id')
.get(function (req, res) {
Sensor.findById(req.params.sensor_id,function(err, sensorInfo) {
if (err)
res.send(err);
res.send(sensorInfo);
});
});
This allows me to retrieve the data when I do http://localhost:4000/sesnors_home/45000cbsfdhjbnabfbajhdb
(45000cbsfdhjbnabfbajhdb = Object id from the MongoDB )
Now my goal is to have several users to my application. I have my mongoose schema set up and the mongoDB looks like this :
Here is the issue: I wanna retrieve data corresponding to John Peterson based on his _id that is "John".Instead of doing this http://localhost:4000/sesnors_home/45000cbsfdhjbnabfbajhdb I wanna do something like this http://localhost:4000/sesnors_home/John and retrieve all the data specific to John. I tried various methods but still stuck with this issue. I tried using req.params._id and also some Mongodb queries on the User Collection but still no luck. Please suggest some ideas.
Thanks!
UPDATE:
I tried using the following code :
router.route('/sensors_home/:id')
.get(function (req, res) {
res.send(_id.toString());
User.findOne({_id: req.params._id} ,function(err, sensorInfo) {
if (err)
res.send(err);
res.send(sensorInfo);
});
});
This gives me the following error :
ReferenceError: _id is not defined

Have you tried the following?
router.route('/sensors_home/:_id')
.get(function (req, res) {
Sensor.findOne({_id: req.params._id},function(err, sensorInfo) {
if (err)
res.send(err);
res.send(sensorInfo);
});
});

Related

Express - return certain documents with named route parameters using axios

I'm having trouble communicating between the frontend and backend for a selected GET request.
I am using a React frontend with an express/mongoose setup out in the backend.
In the frontend, I do a GET call using axios for:
axios.get('/api/orders/', {
params : {
name: this.props.user.name // user name can be Bob
}
})
And in the backend I'm having a hard time understanding the correct method I would need to do to query the database (example below doesn't work). I found stuff with .select but even then I still can't get it to work:
router.get('/orders', function(req, res) {
Order.find({}).select(req.params).then(function (order) {
res.send(req.params);
})
});
I also tried doing this to see if I can even get the params to send properly and to no demise:
router.get('/orders/:name', function(req, res) {
res.send('client sent :',req.query.name);
});
The orders document model holds objects that house an ordered array and a name (type: String) attached to the object. The Mongoose scheme for the order:
const orderScheme = new Schema({
name : { type : String },
orders : { type : Array}
});
In my MongoDB, I can see all the "Master Orders" send back. Each master order has the name of who submitted it, plus all the orders within (there can be a ton of orders).
What I'm trying to exactly do is pull up all orders that have a certain name. So if I search "TestAccount", I'll get all of bob's orders. I've included an image below:
Any pointers?
Client-side:
axios.get('/api/orders/' + this.props.user.name)
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
You need to handle the Promise when resolved/rejected.
Server-side:
router.get('/orders/:name', function(req, res) {
return Order.find({name: req.params.name}).then(function(orders) {
// return orders when resolved
res.send(orders);
})
.catch(function (error) {
// handle error
console.log(error);
})
});
You did not specify a named route parameter in your route path.
You also aren't accessing the name property by using req.params only.
You should use Model.find() conditions parameter to specify which document[s] you're trying to find. Query.prototype.select() is for filtering document fields.

TypeError: Cannot read property '_id' of undefined at insertDocuments at insertOne

I was trying to insert a record into a collection when this error was thrown. I went through the mongodb doc on insertOne and I understand that mongod will automatically add the _id when it is not specified as in my case, so I'm wondering why there is an undefined id error.
Here's the code I'm working with, first the api route and the data I'm trying to insert
app.post('/api/contacts', (req, res) => {
// retrieve the user being added in the body of the request
const user = req.body;
// obtain a reference to the contacts collection
const contactsCollection = database.collection('contacts');
// insert data into the collection
contactsCollection.insertOne(user, (err, r) => {
if (err) {
return res.status(500).json({error: 'Error inserting new record.'});
}
const newRecord = r.ops[0];
return res.status(201).json(newRecord);
});
});
The json data for inserting
{
"name": "Wes Harris",
"address": "289 Porter Crossing, Silver Spring, MD 20918",
"phone": "(862) 149-8084",
"photoUrl": "/profiles/wes-harris.jpg"
}
Database connection to the to the database hosted on mlab is successful with no errors. What could possibly be wrong here and how do I go about fixing this error?
The error message means that the object that you are passing into insertOne is undefined (and hence it can’t read the _id property of of it). You might like to look at what exactly req.body contains as that is what is passed as user. (I don’t know TypeScript but, in node/express, I have had errors like this when I didn’t set up bodyParser correctly)
Faced a similar problem. Solved and it by using body-parser and then parsing the json object being sent as follows:
const bodyParser = require('body-parser');
app.use(bodyParser.json());
// parse application/json
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
})

Sanitizing input fields in express app

I have several input fields for emails on my website. For these, I have 1 POST-route:
app.post('/', function(req, res){
Email.create(req.body.email, function(err, newEmail){
if(err){
console.log(err);
} else {
res.redirect('/');
};
});
});
The bootcamp I am learning from tells me that nefarious actors could use scripts in these inputs. However, when I try something like this:
<script>alert('test')</script>
nothing happens. In fact, it just gets added to my mongo database.
I installed express-sanitizer anyway as the bootcamp suggested and did this:
app.post('/', function(req, res){
req.body.email = req.sanitize(req.body.email);
Email.create(req.body.email, function(err, newEmail){
if(err){
console.log(err);
} else {
res.redirect('/');
};
});
});
However, when I do this and I input something I get an error stating 'ObjectParameterError' when I put in any string or script.
My app.use's look like this:
app.use(bodyParser.urlencoded({extended: true}));
app.use(expressSanitizer());
Any suggestions on how to best protect myself against scripts and how to implement express-sanitizer correctly?
It might be an issue with how you're doing the value changing.
I've done mine like this and it works:
const expressSanitizer = require('express-sanitizer')
let bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true}))
//For Sanitising SQL
app.use(expressSanitizer())
And then when I want to sanitise:
//Pulling the sanitised values from request body
var name = req.sanitize(req.body.name)
var email = req.sanitize(req.body.email)
Instead of sanitizing entire object try to sanitize only the required one.
req.body.email = req.sanitize(req.body.email) should look like this req.body.email.yoursanitizationfield = req.sanitize(req.body.email.yoursanitizationfield);
req.body.email.yoursanitizationfield = req.sanitize(req.body.email.yoursanitizationfield);
Email.create(req.body.email, function(err, newEmail){
if(err){
console.log(err);
} else {
res.redirect('/');
};
});
});```
Can I suggest adding some debugging to get insights to program execution. Add a console.log(req.body.email); after req.body.email = req.sanitize(req.body.email); to see if that has worked? (Or indeed if the execution has even reached that point.)

Post TypeScript Object without '_id' field?

I use Express, Mongoose and Angular 2 (TypeScript) making an web app. Now I want to post a MyClass Instance without any _id field.
In mongoose we could use _id to do a lot of operations on mongoDB, so here is what I have done on the server side using mongoose
router.post('/', function(req, res, next) {
Package.create(req.body, function (err, post) {
if (err) return next(err);
res.json(post);
});
});
/* GET /package/id */
router.get('/:id', function(req, res, next) {
Package.findById(req.params.id, function (err, post) {
if (err) return next(err);
res.json(post);
});
});
/* PUT /package/:id */
router.put('/:id', function(req, res, next) {
Package.findByIdAndUpdate(req.params.id, req.body, function (err, post, after) {
if (err) return next(err);
res.json(post);
});
});
To contain the field _id I created a ts Class like this:
export class Package{
constructor(
public guid: string,
...
[other fields]
...
public _id: string
){}
}
Please note the _id at the end.
In my angular 2 service I am doing this to post the json object to server
//create new pakcage
private post(pck: Package): Promise<Package> {
let headers = new Headers({
'Content-Type': 'application/json'
});
return this.http
.post(this.packageUrl, JSON.stringify(pck), { headers: headers })
.toPromise()
.then(res => res.json())
.catch(this.handleError);
}
Then I received an error as shown in the screenshot below:
In which it indicates that the object I post back got a empty _id field.
How do I post a ts class without the _id field or should I do it totally differently?
Since no one has given an answer I went to the internet and found a good example of how to implement a Angular2 -- Mongoose -- Express System.
https://github.com/moizKachwala/Angular2-express-mongoose-gulp-node-typescript
A very good example with the original Hero App from official tutorial. Although it is based on RC1 but it provides a good start point on how to do the RESTFUL Request properly.
Hope this would help someone who is looking for a similar answer.

concurrency issues while upserting and then reading the data from mongodb using mongoose

Hi I am trying to build an application which upserts data and fetches from the mongodb baser on the userid.This approach works fine for a single user.But when i try hitting for multiple users say 25 the data fetched seems to be null. Below is my upsert code
collection.update({'USER_ID': passVal.ID},
{'RESPONSE': Data}, { upsert: true }, function (err) {
if (err) {
console.log("Error in saving data");
}
var query = collection.findOne({'USER_ID': passVal.ID});
query.select('RESPONSE');
query.exec(function (err, data) {
if (err) return handleError(err);
console.log(data.RESPONSE);
});
})
I always get an error insome cases as data is null.I have written the read code in the call back of upsert only.I am stuck here any help regarding this will be much helpful.