I need to insert an array in mongoDB but an empty array is inserted all the time. What am I doing wrong?
My schema
const taskSchema = new Schema({
username: { type: String, required: true },
title: { type: String, required: true },
subtasks: [String] //how to define array as type here?
}, {
timestamps: true,
});
data to be updated:
{
"username": "test",
"title": "test",
"subtasks": ["task1", "task2"]
}
Update: it works now.
I had an err in route file, I had "subtasksArray" instead of subtasks there:
const router = require('express').Router();
let TodaysTask = require('../models/todaysTask.model');
router.route('/add').post((req, res) => {
const username = req.body.username;
const title = req.body.title;
const subTaskArray = req.body.subtasksArray; //it should be subtasks here
const newTodaysTask = new TodaysTask({
username,
title,
subtasksArray
});
newTodaysTask.save()
.then(() => res.json('Task added!'))
.catch(err => res.status(400).json('Error: ' + err));
});
you defined the attribute tasks but are trying to insert subtasks.
Maybe define the attribute subtasks
Related
I am trying to add an item to a MongoDB array with RESTAPI through Axios. I thought it would look similar to the push method but I have no idea how to do that.
my Model is of a person:
const Schema = mongoose.Schema;
const PersonSchema = new Schema({
name: String,
password: String,
friends: [],
missions: []
})
const personModel = mongoose.model('Person', PersonSchema);
I want to add a mission to the mission array of a person.
and for example, in order to add a new Person, I use NodeJS and API:
(api.js)
router.post('/api/people', (req, res) => {
const personToAdd = req.body;
const newPersonPost = new personModel(personToAdd);
newPersonPost.save((e) => {
if (e) {
console.log("error");
}
});
res.json({
msg: 'Received'
})
});
and in the client side I use Axios:
axios({
url: 'http://localhost:8080/api/people',
method: 'POST',
data: dataToUpdate
})
.then(() => {
console.log('axios sent info to server');
}).catch((e) => {
console.log('error' + e);
})
Thank you so much!
express
router.post('updating mission endpoint url', async (req, res) =>
try {
const query = { /* content */}; /* write a query to retrieve the concerned user by using a unique identifier */
let person = await personModel.findOne(query);
person.missions.push(req.body.mission);
personModel.save();
} catch (err) {
console.log(err);
}
});
client
In the client side you just have to put the mission you want to add in data like you did above with the right endpoint url and you should add a unique identifier for the user you want to add mission to.
[] will not assign array type to your variable.
Change your schema file with the following:
const Schema = mongoose.Schema;
const PersonSchema = new Schema({
name: { type: String },
password: { type: String },
friends: { type: Array },
missions: { type: Array }
})
Update the db model entity file with following
First method:
const Schema = mongoose.Schema;
const PersonSchema = new Schema({
name: String,
password: String,
friends: {type : Array},
missions: {type : Array}
})
const personModel = mongoose.model('Person', PersonSchema);
Second Method :
const Schema = mongoose.Schema;
const PersonSchema = new Schema({
name: String,
password: String,
friends: [{ type: String }],
missions: [{ type: String }]
})
const personModel = mongoose.model('Person', PersonSchema);
You can update the array object as per your requirements.
You just want to be using the $push update operator, very simple, like so:
db.collection.updateOne(
{
_id: user._id
},
{
"$push": {
"missions": {
mission: newMission
}
}
})
Mongo Playground
I'm creating the backend of my project. In this project, there are some groups, and each groups has its partecipant. I would like to make a function in nodejs that retrive all the groups that, in the partecipant field(which is an array), has a given user.
Here is the schema of group:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const GroupSchema = new Schema({
name: {
type: String,
required: true,
unique: true,
},founder:{
type:String,
required: true,
}, partecipants:{
type: Array,
required:false,
}, files: {
type:Array,
required: false,
}
})
const Group = mongoose.model('Group', GroupSchema);
module.exports = Group;
For now, I wrote only this:
const getGroupByUser = (req, res) => {
const user = req.body.user;
Group.find()
.then(files => res.json(files))
.catch(err => res.status(400).json('ERROR:'+err))
}
But it obviusly returns all the groups. I don't know if there is a way to make it in the promise, or if I have to cycle throught the array, like a linear search, but for multiple cases. Any idea? Thank you
const getGroupByUser = (req, res) => {
const user = req.body.user;
const id = req.query.id;
// if id is saved as objectId covert it using Types.ObjectId(id)
Group.find({partecipants: id})
.then(files => res.json(files))
.catch(err => res.status(400).json('ERROR:'+err))
}
using {partecipants: id} you tell to mongoDb to find all group that have into the array the userId you pass in query params
I'm trying a to make a post request to save new data to one of my subdocuments, but I'm getting an error when trying to access the subdocument in the function. It keeps coming back as undefined. How can I get a specific user by id and create and add new data the one it's subdocuments?
model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const ClassworkSchema = new Schema({
name: String,
time: Date,
todo: String,
isDone: false
});
const OutcomesSchema = new Schema({
name: String,
time: Date,
todo: String,
isDone: false,
isApproved: false
})
const MeetupSchema = new Schema({
name: String,
time: Date,
location: String,
attended: false
})
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
classwork:{type: [ClassworkSchema], default: []},
outcomes: [OutcomesSchema],
meetups: [MeetupSchema],
});
module.exports = User = mongoose.model('users', UserSchema);
controller
classworkRouter.post("/:userId/", (req, res) => {
User.findById(req.params.user_id, (err, user) => {
if (err) return err;
new_classwork = new classwork();
(new_classwork.name = req.body.name),
(new_classwork.date = req.body.date),
(new_classwork.todo = req.body.todo),
(new_classwork.isDone = req.body.isDone);
console.log(new_classwork);
user.classwork = {};
user.classwork.name = req.body.classwork.name;
user.classwork.todo = user.classwork.todo;
if (user.classwork === undefined) {
user.classwork.push(new_classwork);
} else {
user.classwork = [new_classwork];
}
user.save(function (err, data) {
if (err) res.send(err);
res.json({ message: "work added", data: data });
});
});
});
you can see the error in the terminal in the following phto:
in this part of code
new_classwork = new classwork()
you shoud defined the new_classwrok like this :
let new_classwork = new classwork()
and new classwork() is not defined, you must to require Model of classwork in controller..
in schema file export schemas like this :
const User = mongoose.model('users', UserSchema);
const Classwork = mongoose.model('Classwork', ClassworkSchema );
module.exports = {
User : User ,
Classwork : Classwork
}
in controller.js
const {User} = require('../models/certification');
const {Classwork } = require('../models/certification');
after require models you can use new Crosswork like this :
note: Classwork with uppercase character
let new_classwork = new Classwork()
I'm fairly new to node & express, I'm trying to implement a register application.
I have 2 models, both models have one common field 'empID'.
const RegisterEntriesSchema = mongoose.Schema({
empID: Number,
registerType: String,
registerItemsQuantity: Number,
registerItemsDesc: String
}, {
timestamps: true
});
const RegisterEmpSchema = mongoose.Schema({
empID: Number,
empName: String,
empPhone: String,
empProj:String
}, {
timestamps: true
});
For my get call in which I need to merge the values, I get from RegisterEmpSchema with its corresponding
employee details from RegisterEmpSchema.
exports.findAllRegisterEntries = (req, res) => {
registerEntriesModel.find()
.then(result => {
var updatedResponse=[];
console.log(result[0].empID);
for(var i=0;i<result.length;i++){
registerEmpModel.find({ empID: result[i].empID })
.then(result2 => {
**//unable to access result here**
}).catch(err => {
console.log("exception catch called findAllRegisterEntries, find employee details "+err);
});
}
res.send(updatedResponse);
}).catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while retrieving register."
});
});
};
I basically need to get register data and its corresponding employee data.
How do I modify my find() code to use the key empID and do a join query fetch?
I think you better use populate, add ref to empID inside RegisterEntriesSchema
const RegisterEmpSchema = new mongoose.Schema({
empID: Number,
empName: String,
empPhone: String,
empProj: String
}, {
timestamps: true
});
const registerEmpModel = mongoose.model('RegisterEmpSchema', RegisterEmpSchema, 'registerEmployeeCollection');
const RegisterEntriesSchema = new mongoose.Schema({
registerType: String,
registerItemsQuantity: Number,
registerItemsDesc: String,
empID: {
type: mongoose.Schema.Types.ObjectId,
ref: 'RegisterEmpSchema'
}
}, {
timestamps: true
});
RegisterEntriesSchema.index({ createdAt: 1 }, { expires: '525601m' });
const registerEntriesModel = mongoose.model('RegisterEntriesSchema', RegisterEntriesSchema, 'registerEntriesCollection');
module.exports = {
registerEmpModel, registerEntriesModel,
}
then use populate() to populate the RegisterEntriesSchema with correspondence empID
RegisterEntriesSchema.
find().
populate('empID').
exec(function (err, data) {
if (err) return console.log(err);
res.send(data);
});
check mongoose docs: https://mongoosejs.com/docs/populate.html
I can't save anything to my new mongodb collection because I keep getting this error
"message": "Cast to String failed for value \"{}\" at path \"body\""
I've successfully used models to add data to my mongodb collections with no issue in the past, but I tried to create a new model today and when I decided to test it using postman I kept getting this error . I tried reading online but couldn't find an answer, please help.
Here's my schema for this
const mongoose = require("mongoose");
const ticketSchema = new mongoose.Schema({
sender: {
type: String
},
body: {
type: String,
required: true
},
ticketStyle: {
type: String
},
ticketStatus: {
type: String
},
response: {
type: String,
required: false
}
});
const Ticket = mongoose.model("Ticket", ticketSchema);
module.exports = Ticket;
and here is the route
router.post("/support", (req, res) => {
const body = req.body;
const sender = "admin";
const ticketStyle = "userstyle";
const ticketStatus = "pending";
const newTicket = new Ticket({
body,
sender,
ticketStyle,
ticketStatus
});
newTicket
.save()
.then()
.catch(error => {
res.send(error);
});
});
I want add these posts to my collection, but since the "body" key-pair is required and I keep getting this error I'm stuck
Just figured the issue (clumsy mistake), this was due to an issue caused from how I decided to name my variables. I updated the schema and variable names and all worked as intended.
new route:
router.post("/", (req, res) => {
const sender = "admin";
const message = req.body.message;
const ticketStatus = "pending";
const ticketStyle = "userTicket";
const newTicket = new Ticket({
sender,
message,
ticketStyle,
ticketStatus
});
newTicket
.save()
.then(tickets => {
res.redirect(req.originalUrl);
console.log("Successfully saved to database");
})
.catch(err => {
res.status(400).send("unable to save to database");
console.log("unable to save to database");
});
});
And I also updated the schema name too.
const ticketSchema = new mongoose.Schema({
sender: {
type: String,
required: true
},
message: {
type: String,
required: true
},
ticketStatus: {
type: String
},
ticketStyle: {
type: String
},
reply: {
type: String
}
});
The issue was from requesting the body data in the route as just req.body, not req.body.message so I guess the code was trying to save/use the whole JSON file as a string (I guess) .