not able to save array of ids mongo - node.js

I have an Order model that looks like this
const mongoose = require('mongoose');
const orderSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
products: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true }]
});
module.exports = mongoose.model('Order', orderSchema);
This is the OrderController:
exports.orders_create_order = (req, res, next) => {
console.log("======This is what we're sending to the endpoint==============================");
console.log(req.body);
console.log('====================================');
const order = new Order({
_id: mongoose.Types.ObjectId(),
products: req.body.products
});
order.save().then(result => {
console.log('====================================');
console.log("This is what is getting saved");
console.log(result);
console.log('====================================');
res.status(201).json({
message: "Order stored",
createdOrder: {
_id: result._id,
products: result.product
}
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
};
It takes an array of objects that I am sending from the a react frontend like so:
axios.post("http://ocalhost:4500/orders/", {"products":"[5e9e7edb4e0e5100041e3aa1, 5e9e85824e0e5100041e3aa4, 5e9e859d4e0e5100041e3aa6]"})
.then(res => {
console.log('=======This is the data we are getting from saving new wishlist at the frontend=============================');
console.log(res.data);
console.log('====================================');
})
.catch(err =>
console.log(`The error we're getting from the backend--->${err}`))
the error I am getting here is :
message: 'Cast to Array failed for value "[5e9e7edb4e0e5100041e3aa1, 5e9e85824e0e5100041e3aa4, 5e9e859d4e0e5100041e3aa6]" at path "products"',
Please tell me what am I doing wrong here?

You are tring to send products as string, it should be an array like this:
{
"products": [
"5e9e7edb4e0e5100041e3aa1",
"5e9e85824e0e5100041e3aa4",
"5e9e859d4e0e5100041e3aa6"
]
}

Related

how to query with out [0] in mongoose?

I'd like to make a query that moves ytbReqTb's data to ytbChannelTb.
This is my Schema(ytbReqTb)
const ytbReqTbSchema = new Schema({
_id: mongoose.Schema.Types.ObjectId,
ytbChannel: String,
ytbSubscribe: Number,
ytbHits: Number
}
and this is my other Schema(ytbChannelTb).
{
const ytbChannelTbSchema = new Schema({
_id: mongoose.Schema.Types.ObjectId,
ytbChannel: String,
ytbSubscribe: Number,
ytbHits: Number,
}
So I query like this and it works.
router.put('/recognize/:youtuber', async (req, res, next) => {
const ytbReq = await YtbReqTb.find({ 'ytbChannel' : req.params.youtuber });
await YtbReqTb.remove({ 'ytbChannel' : req.params.youtuber });
const ytbChannelTb = new YtbChannelTb({
_id: new mongoose.Types.ObjectId(),
ytbChannel: ytbReq[0].ytbChannel,
ytbSubscribe: ytbReq[0].ytbSubscribe,
ytbHits: ytbReq[0].ytbHits,
});
ytbChannelTb.save()
.then(result => {
res.status(201).json();
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
});
But it doesn't work without '[0]'. Is there a way to query without '[0]'?
If query can't take out '[0]', could you tell me why?
the result of find is a array, if you want result be an object so use findOne instead of find like this:
const ytbReq = await YtbReqTb.findOne({ 'ytbChannel' : req.params.youtuber });

How to delete comment that is inside of Post schema?

I'm working on social network app where user can make post and comment. I'm trying to delete comment that is inside of a post. I work with MERN (mongoose, express, react, nodejs). I can successfully delete post, but don't know how to delete its comment.
This is my Mongo connection:
const db = config.get('mongoURI') mongoose.connect(db,{useNewUrlParser: true,useUnifiedTopology: true})
.then(() => console.log('Connected to MongoDB.'))
.catch(err => console.log('Fail to connect.', err))
this is Post Schema
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const PostSchema = new Schema({
userID: {
type: Schema.Types.ObjectId,
ref: 'user'
},
content: {
type: String,
required: true
},
registration_date: {
type: Date,
default: Date.now
},
likes: [
{
type: Schema.Types.ObjectId,
ref: "user"
}
],
comments: [
{
text: String,
userID: {
type: Schema.Types.ObjectId,
ref: 'user'
}
}
]
})
module.exports = User = mongoose.model('posts', PostSchema)
and here is where i tried to delete it:
router.delete("/comment/:postId/:commentId", auth, function (req, res) {
Post.findByIdAndUpdate(
(req.params.postId),
{ $pull: { comments: req.params.commentId } },
{ new: true }
)
.then(post => console.log(post)
.then(() => {
res.json({ success_delete: true })
})
.catch(() => res.json({ success_delete: false })))
});
Well, I think you are creating an app named DevConnector. So I wrote code for the same in the past.
router.delete('/comment/:id/:comment_id', auth, async (req, res) => {
try {
const post = await Post.findById(req.params.id);
// Pull out comment
const comment = post.comments.find(
comment => comment.id === req.params.comment_id
);
// Make sure comment exists
if (!comment) {
return res.status(404).json({ msg: 'Comment does not exist' });
}
// Check user
if (comment.user.toString() !== req.user.id) {
return res.status(401).json({ msg: 'User not authorized' });
}
// Get remove index
const removeIndex = post.comments
.map(comment => comment.user.toString())
.indexOf(req.user.id);
post.comments.splice(removeIndex, 1);
await post.save();
res.json(post.comments);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});

Node.js API find a MongoDB Document by passing ObjectID

The following GET ALL route is working. The second route below, I am trying to retrieve a single Employee document by ObjectId. This is not working. Please help. My Employee model is at the bottom.
// Get all Employees
router.get("/", async (req, res) => {
try {
const employees = await Employee.find();
res.json(employees);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
// Get Single Employee by ObjectId
router.get("/:id", (req, res) => {
try {
const employees = await Employee.find(id)
res.json(employees);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
const employeeSchema = new mongoose.Schema({
_id: {
type: mongoose.Schema.Types.ObjectId,
required: true,
},
fname: {
type: String,
required: false,
},
lname: {
type: String,
required: false,
},
});
use findById(id) or find({_id: id})
https://mongoosejs.com/docs/api.html#model_Model.find

Creating REST API to handle JSON data from different sensors on Node.js & MongoDB

I am trying to make a REST API to handle JSON data from sensors(thermometer, hygrometer) to store and process temperature and humidity data. However at the moment, I am not getting the data directly from sensors yet so I am planning on sending dummy data to the node.js server from a client through http GET/POST requests.
I am using Node.js as a server and I'm trying to save into mongodb using mongoose.
When trying to design this system using mvc design pattern, I was at first trying to only make one sensor.model.js & sensor.controller.js but the problem arose when I had to deal with two different sensor data where each sends its temperature data or humidity data. So I wasn't sure how I should design the API.
I am supposing that it'd be a better option to just POST each sensor data separately to such as "localhost:3000/sensors/thermometer/" and "localhost:3000/sensors/hygromometer/". I can now successfully send POST requests to "localhost:3000/sensors/thermometer/" and "localhost:3000/sensors/hygromometer/" but I want to able to send GET method to fetch all data from '/sensors' sorted by sensor_type. How can I make this possible? Is there any good way to come up with this?
I put codes for sensor.js and thermometer.js below. hydrometer.js is the exact same as thermometer.js so I did not bother to put it.
Thank you so much in advance.
// sensors.model.js
const mongoose = require('mongoose');
const sensorSchema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
// this method below doesn't work.
sensor_type: {type: String, ref: 'Hygro'},
sensor_type: {type: String, ref: 'Thermo'},
//time : { type : Date, default: Date.now },
temperature: {type: Number},
humidity: {type: Number}
});
module.exports = mongoose.model('Sensor', sensorSchema);
//____________________________________________________________________________
// sensors.route.js
router.get('/', (req, res, next) => {
Sensor.find()
.select('_id sensor_type temperature humidity')
.exec()
.then(docs => {
res.status(200).json({
sensors: docs.map(doc => {
return {
_id: doc._id,
sensor_type: doc.sensor_type,
temperature: doc.temperature,
humidity: doc.humidity + "%"
}
})
});
})
.catch(err => {
res.status(500).json({
error : err
});
});
//___________________________________________________________________________
// thermometer.model.js
const mongoose = require('mongoose');
const thermoSchema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
sensor_type: {type: String, required: true},
temperature: {type: Number, required: true}
});
module.exports = mongoose.model('Thermo', thermoSchema);
//___________________________________________________________________________
// thermometer.route.js
router.post('/', (req, res, next) => {
// create sensor object
const thermo = new Thermo({
_id: new mongoose.Types.ObjectId(),
sensor_type: req.body.sensor_type,
temperature: req.body.temperature
});
//save thermo obj into the db
thermo
.save()
.then(result => {
console.log(result);
res.status(201).json({
message: 'Created sensor data successfully',
createdSensor_data: {
sensor_type: result.sensor_type,
temperature: result.temperature,
_id: result._id
}
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
}
Can a sensor store humidity and temperature at the same time?
if not then the design could be simple:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const sensorSchema = new Schema({
_id: Schema.Types.ObjectId,
type: {
type: String,
required: true,
enum: ['Hydro', 'Thermo']
},
//time : { type : Date, default: Date.now },
// for the time I use mongoose built in { timestamps: true }
// temperature: {type: Number},
// humidity: {type: Number}
// store value instead. if it's type 'Hydro' you know it's humidity
value: {
type: Number,
required: true
}
}, { timestamps: true } );
// timestamps: true gives you createdAt and updatedAt automatically
module.exports = mongoose.model('Sensor', sensorSchema);
to get all the sensors
// sensors.route.js
router.get('/', (req, res, next) => {
Sensor.find()
.select()
.exec()
.then(result => {
res.status(200).json({
sensors: result.map(item => {
return item._doc
})
});
})
.catch(err => {
res.status(500).json({
error: err
});
});
})
For post request
router.post('/', (req, res, next) => {
// create sensor object
const sensor = new Sensor({
// _id: new mongoose.Types.ObjectId(),
// you dont new to add _id, Mongoose adds it by default
type: req.body.sensor_type,
value: req.body.temperature
});
//save it
sensor
.save()
.then(result => {
console.log(result);
res.status(201).json({
message: 'Created sensor data successfully',
createdSensor_data: result._doc // you can access the data on the _doc property
});
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
});
});
})
I would also validate req.body for data and throw an error if there isn't any.

Get username from jwt Express app

I have 3 routes in my code , for Users, for Products and For Orders.
I use jwt and generate tokens for users, and I want to assign orders to token Owners.
Here's my Order Model :
var mongoose = require('mongoose');
var orderSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId ,
product: {type: mongoose.Schema.Types.ObjectId, ref: 'Product'},
quantity: {type: Number , default: 1},
user_name: String
});
module.exports = mongoose.model('Order', orderSchema);
And here's my middleware to check Authenticate (It's imported as checkAuth) :
module.exports = (req,res,next) => {
try {
var decoded = jwt.verify(req.headers.token, secretjwt);
req.userData = decoded;
next();
} catch (error) {
return res.status(401).json({
'error': 'Auth Failed',
'details': error.message
});
}
Here's my post api for adding orders, What Should I write as user_name to assign it to the user (I don't want to get username as a body parameter)?
router.post('/newOrder', checkAuth, (req,res,next) => {
var order = new Order({
quantity: req.body.quantity,
product: req.body.productId,
user_name: // WHAT SHOULD IT BE?
});
order.save()
.then(result => {
res.status(200).json(result);
})
.catch(err => {
res.json(200);
});
});
Thanks in advance!
Instead of
req.userData = decoded
put
req.body.userData = decoded
And put user_name: req.body.userData in following snip
router.post('/newOrder', checkAuth, (req,res,next) => {
var order = new Order({
quantity: req.body.quantity,
product: req.body.productId,
user_name: // WHAT SHOULD IT BE?
});
order.save()
.then(result => {
res.status(200).json(result);
})
.catch(err => {
res.json(200);
});
});

Resources