How to insert an array to mongodb using express.js and axios - node.js

I am developing an application in which I need to send an array with the time and amount of food. When I print the console log on the front (vuejs and axios), I can see the array with the correct information, but when I send that array to the back (express and mongoose) it arrives as Undefined. I am providing below the front my functions and the code of my back.
I`m using MongoDB as database.
Could you please help me?
FRONTEND: (vuejs)
addMealList() {
if (this.editedIndex > -1) {
Object.assign(this.mealList[this.editedIndex], this.mealInformations);
console.log(this.mealList);
} else {
this.mealList.push(this.mealInformations);
console.log(this.mealList);
}
this.close()
},
addToAPI() {
// console.log(this.mealList);
axios.post(`${this.serverUrl}devices/register`, this.mealList)
.then((res) => {
console.log(this.mealList);
console.log(res.data);
})
.catch((error) => {
console.log(error);
});
},
```
BACKEND: (mongoose and express)
Schema File:
```
const mongoose = require('mongoose');
const mealSchema = new mongoose.Schema({
time: {
type: String,
required: true
},
quantity: {
type: String,
required: true
}
});
const deviceSchema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
mealList: [mealSchema],
creation_information: {
date: {
type: Date,
default: Date.now
},
by: {
type: String,
required: true
}
}
}, { collection : 'device' });
module.exports = mongoose.model('device', deviceSchema);
Express code:
router.post('/register', (req, res) => {
console.log(req.body.mealList);
console.log(req.user);
const device = new Device({
_id: new mongoose.Types.ObjectId(),
mealList: [ req.body.mealList ],
creation_information: {by: req.user._id}
});
console.log(device);
if (device.mealList && device.mealList.length) {
device.save().then(result =>{
console.log(result);
res.status(201).json({
message: "Hadling POST requests to device",
createdDevice: result
});
})
.catch(err =>{
console.log(err);
res.status(500).json({
error: err
})
});
}else {
console.log('array is empty');
}
});
I expected to see my Meals array with time and quantity, but I`m getting this on my terminal
undefined
{ _id: 5cfbde0d5bd9cd0e168f14cf,
mealList: [ undefined ],
creation_information: { by: 'Lorena Meyas', date: 2019-06-08T16:10:53.756Z } }
{ _id: 5cfbde0d5bd9cd0e168f14cf,
mealList: [ undefined ],
creation_information: { by: 'Lorena Meyas', date: 2019-06-08T16:10:53.756Z },
__v: 0 }

Related

Post an array of referenced object id's Mongoose NodeJs

I want to be able to post several Object id's into the array,, I have two models control and subcontrol is referenced in the control model as an array. The idea is a control number might have sub control number under it
router.post(
'/add',
auth,
role.checkRole(role.ROLES.Admin, role.ROLES.Regulator),
async (req, res) => {
try {
const subControl = new SubControl({...req.body}); // do something to map over these items
const subControlDoc = await subControl.save();
const control = new Control({...req.body, subControl: subControlDoc._id});
const savedControl = await control.save();
res.status(200).json({
success: true,
message: `Control has been added successfully!`,
control: savedControl
});
} catch (error) {
return res.status(400).json({
error
// error: 'Your request could not be processed. Please try again.'
});
}
}
);
I'm able to save one object ID of the subControl although I defined the subControl as an array in the control model. How can I insert multiple subControls ?
EDIT
I edited my solution as suggested in the answers:
router.post(
'/add',
auth,
role.checkRole(role.ROLES.Admin, role.ROLES.Regulator),
async (req, res) => {
try {
const subControl = new SubControl({...req.body});
const subControlDoc = await subControl.save();
const control = new Control({...req.body});
control.subControl.push(subControlDoc._id);
const savedControl = await control.save();
res.status(200).json({
success: true,
message: `Control has been added successfully!`,
control: savedControl
});
} catch (error) {
return res.status(400).json({
error
// error: 'Your request could not be processed. Please try again.'
});
}
}
);
My postman:
{
"mainControl": "nn",
"controlDescription": "controldescription",
"subControl":
[
{
"subControlNo": "1-2"
},
{
"subControlNo": "1-2-1"
}
]
}
Control model:
const ControlSchema = new Schema({
_id: {
type: Schema.ObjectId,
auto: true
},
mainControl: {
type: String
},
subControl: [
{
type: Mongoose.Schema.Types.Mixed,
ref: 'SubControl'
}
],
controlDescription: {
type: String,
trim: true
},
updated: Date,
created: {
type: Date,
default: Date.now
}
});
module.exports = Mongoose.model('Control', ControlSchema);
SubControl Schema:
const SubControlSchema = new Schema({
_id: {
type: Schema.ObjectId,
auto: true
},
subControlNo: {
type: String
},
updated: Date,
created: {
type: Date,
default: Date.now
}
});
module.exports = Mongoose.model('SubControl', SubControlSchema);
Response I'm getting:
Not want I want to achieve, I want to be able to save several subControl, each subControl to be saved as an individual ObjectId rather than saving it as a String with one ObjectId

How to find top 10 most viewed and top 10 most liked data in mongoose

I have a Post table in mongo db. There are 1000 of post in the table. I tried following query to fetch top 10 most viewed and top 10 most liked post but I don't get any expected output. How to get that output, please help me.
This is my Post model in mongo db database where made two fields for views and likes.
const mongoose = require("mongoose");
const { Schema } = mongoose;
const postSchema = new Schema({
title: {
type: String,
required: true,
},
description: {
type: String,
},
image: {
type: String,
},
likes: [User],
views: {
type: Number,
},
createdBy: {
type: Schema.Types.ObjectId,
ref: "users",
},
createdAt: {
type: Date,
default: Date.now,
},
});
//Controller
topViewPosts(req, res) {
try {
Post.find()
.sort({ views: -1 })
.limit(10)
.then((posts) => {
console.log(posts);
res.status(200).json({
message: "Fetch seccessful",
posts: posts,
});
})
.catch(() => {
res.status(500).json({
error: error,
});
});
} catch (error) {
res.status(500).json({
error: error,
});
}
},
topLikePosts(req, res) {
try {
Post.find()
.sort({ likes: -1 })
.limit(10)
.then((posts) => {
console.log(posts);
res.status(200).json({
message: "Fetch seccessful",
posts: posts,
});
})
.catch(() => {
res.status(500).json({
error: error,
});
});
} catch (error) {
res.status(500).json({
error: error,
});
}
},
use the sort property :
router.get("/yourrouter", async(req, res) => {
try {
const variable = await Modal.find()
.sort(function(a,b) {
if (a.likes > b.likes) return -1
if (a.likes < b.likes) return 1
return 0
})
res.status(200).json(post)
} catch (error) {
res.status(500).json(error)
}
});

Mongoose: how to only populate, sort and return a nested object?

I have a User schema, with a messages array. The message array is filled by conversations id and referenced to a Conversation schema.
I want to fetch all conversations from a user, sort them by unread and then most recent messages. Finally, I must only return an array of lastMessage object.
For the moment, I have only managed to populate the whole user object.
Here is the Conversation Schema:
const conversationSchema = new mongoose.Schema(
{
name: { type: String, required: true, unique: true },
messages: [{ message: { type: String }, authorId: { type: String } }],
lastMessage: {
authorId: { type: String },
snippet: { type: String },
read: { type: Boolean },
},
},
{ timestamps: true }
);
conversationSchema.index({ name: 1 });
module.exports = mongoose.model("Conversation", conversationSchema);
And here is my code:
router.get("/conversations", async (req, res) => {
try {
const { userId } = req.query;
const user = await User.findById({ _id: userId }).populate("messages");
.sort({ updatedAt: 1, "lastMessage.read": 1 });
return res.json({ messages: user.messages });
} catch (err) {
console.log("error", err);
return res.json({ errorType: "unread-messages-list" });
}
});
How to do this?

findOneAndUpdate seems to be doubling my $inc count

I'm trying to post a comment on to my posts for my MERN app but I'm running into an issue where the comment (Posts.findOneAndUpdate) seems to posting the comments twice. I read a few posts on SO that described the issue to be the way mongoose handles queries but I must be missing something.
If anyone could explain what I'm doing wrong I would greatly appreciate it!
Route I'm using:
router.post('/newReply/:id', async function(req, res) {
const body = req.body
if (!body) {
return res.status(400).json({
success: false,
error: 'No text entered!',
})
}
const reply = new Replies(body)
if (!reply) {
return res.status(400).json({ success: false, error: err })
}
await Posts.findOneAndUpdate(
{ _id: req.params.id },
{
"$inc": { "replies": 1 },
"$push": { "comments": reply },
},
{
new: true
},
(err) => {
if (err) {
return res.status(404).json({
success: false,
error: err,
message: 'Post not found!',
})
}
return res.status(200).json({
success: true,
id: reply._id,
message: 'Reply created!',
reply: reply.reply,
points: reply.points,
createdAt: reply.createdAt
})
})
.catch(err => console.log(err))
})
Posts Model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create Schema
const PostsSchema = new Schema({
post: {
type: String,
required: true
},
points: {
type: Number,
default: 0
},
voters: {
type: Array
},
upvotedBy: {
type: Array
},
downvotedBy: {
type: Array
},
createdAt: {
type: Date,
default: Date.now
},
replies: {
type: Number,
default: 0
},
comments: {
type: Array
},
user_id: {
type: 'string'
},
deleted: {
type: Boolean,
default: false
}
});
module.exports = Posts = mongoose.model("posts", PostsSchema);

Axios.delete() not triggering as expected

So I've got a classes Model which contains an array of people who will attend the class, I am trying to remove people from the classes.
So this is the Model:
const mongoose = require('mongoose');
const classMembersSchema = mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user',
}
})
const classSchema = mongoose.Schema({
location: {
type: String,
required: true
},
type: {
type: String,
required: true
},
name: {
type: String,
required: true
},
time: {
type: String,
required: true
},
classMembers: [classMembersSchema]
});
module.exports = mongoose.model('createClass', classSchema);
The classMembers Array is the one I mentioned that I am trying to remove members from. classMembers: [classMembersSchema].
This is the axios.delete:
deleteClassHandler = () => {
axios.delete('/api/classes/' + this.props.id + '/user/' + this.props.userId)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
});
}
This is the route:
router.delete('/:id/user/:userId', ClassesController.deleteUser);
This is the controller:
exports.deleteUser = (req, res) => {
GymClass.findById({
_id: req.params.id
}, 'classMembers', (err) => {
if (err) {
res.status(401).json({
message: "Error Occured!"
})
} else {
GymClass.findByIdAndDelete({
"classMembers.userId" : mongoose.Types.ObjectId(req.params.userId)
}, (err) => {
if(err) {
console.log('Keeps hitting here!');
res.status(401).json({
message: "Error Occured!"
})
} else {
res.status(200).json({
message: "Success!"
})
}
});
}
})
}
Everything works fine until it hits the console.log('Keeps hitting here!');
At the start of the function the req.params.id which is the class Id of which class we want to modify and the req.params.userId which is the user we want to remove from the Array inside the Model do have the right values but when it gets to that step it gives me the Error.
I'm thinking it could be that it is not finding this:
GymClass.findByIdAndDelete({
"classMembers.userId" : mongoose.Types.ObjectId(req.params.userId)
Since it's in an Array within the classMembers. Any idea or advice to get this to work? Many thanks.

Resources