Insert array into MongoDB subdocument with Node.js - arrays

I currently have a schema which looks as follows:
positionsApplied:[{
position_id:String,
index_position: Number
}],
I also have 3 objects which I need to insert into my database:
How can I insert these into my database through an Ajax call? What Ive tried so far:
Adding the data to an array like this:
["58d6b7e11e793c9a506ffe8f", 0, "58c2871414cd3d209abf4fc1", 1, "58d6b7e11e793c9a506ffe7f", 1]
Which would then be passed through my ajax call like this?(unsure)
$.ajax({
url: "/insertPositionIndex",
type: "POST",
dataType: "json",
data: {
newarray
},
success: function (data) {
console.log(data);
}
})
Inserting into the database is where I'm stuck, how do I break down the array in order to insert it?
app.post('/insertPositionIndex', function(req, res){
var object = req.body.ordered_divs;
console.log(req.body);
User.update(
{ "_id": req.user._id},
{ "$push":
{"positionsApplied":
{
// unsure what to do here?
}
}
}
).exec(function (err, result) {
console.log(result);
res.send({ results: result });
});
});
Any help is greatly appreciated!
* Note the position_id field in the schema is the div_id in the array, also the index-position field is the index_pos in the array.
user schema:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = new Schema({
id: String,
name: String,
companyname: String,
password: String,
email: String,
username: String,
location: String,
role:String,
teamwork:Number,
initiative:Number,
technical_skills: Number,
communication:Number,
employees: String,
profile_image: String,
biodescription: String,
twitter: String,
facebook: String,
instagram: String,
linkedin: String,
biodescription: String,
positionsApplied:[{
position_id:String,
index_position: Number
}],
experience: [{
title: String,
location: String,
company: String,
start: String,
end:String,
description:String
}],
position: [{
_id:String,
title: String,
location: String,
start: String,
term:Number,
description:String,
date: {type: Date, default: Date.now},
applied:[{
candidate_id: String,
profile_image: String,
location: String,
name: String,
_id:String
}],
}],
education: [{
school: String,
location: String,
degree: String,
start: String,
end:String,
description:String,
_id:String
}],
images: [{
one: String,
two: String,
three: String,
four: String,
five:String,
six:String
}],
});
module.exports = mongoose.model('User', User);

Since your Schema is an array of objects and the data that you are getting(as per console of the browser) is also an array of objects why don't you just pass that array itself(the one in the console of the browser) through ajax and use the $each of mongodb $push to save it into the database.
$.ajax({
url: "/insertPositionIndex",
type: "POST",
dataType: "json",
data: {
arrayOfObjects
},
success: function (data) {
console.log(data);
}
})
app.post('/insertPositionIndex', function(req, res){
var object = req.body.ordered_divs;
console.log(req.body);
User.update(
{ "_id": req.user._id},
{
"$push":
{
"positionsApplied":{
$each: req.body.arrayOfObjects
}
}
}
).exec(function (err, result) {
console.log(result);
res.send({ results: result });
});
});
You will have to change the arrayOfObjects keys to match that of your schema positionsApplied keys.

Related

Why is my mongoose populate query throwing "Cannot populate path because it is not in your schema" error?

I'm building a form management program but right now I'm just trying to build a queue system to handle all the forms when they're assigned to someone.
when I call this first function, it should populate the elements of the activeWork array by pulling from each collection that the entries reference, there are several collections that could be referenced in active work, so I'm trying to use the collection type field to determine what collection to pull from, I don't know if I formatted any of this correctly because its my first time building any of this.
import statesPersons from "./statesPersons.schema.js";
export async function getStatesPersonsActiveWorkByProfileId(req, res){
try{
const { profileId } = req.params
const data = await statesPersons.find({profileId})
.populate('statesPersons.activeWork.referenceId')
return res.send({
message: "success",
data: data,
status: 200 })
}catch(e) {
console.error(e.message)
return res.send({
message: "couldn't fetch active work",
data: null,
status: 500 })
}
}
Here is the schema for statesPersons, the collection where active work is stored.
import mongoose, {model, Schema} from "mongoose";
const activeWorkSchema = new Schema({
active: Boolean,
collectionType: {
type: String,
enum: ['messages'],
},
referenceId: {
type: Schema.Types.ObjectId,
refPath: "statesPersons.activeWork.collectionType"
},
sentBy: {
type: Schema.Types.String,
ref: "statesPerson",
},
sentTo: {
type: Schema.Types.String,
ref: "statesPerson",
},
timeRecived: Date,
dueDate: Date,
subject: String,
viewed: Boolean,
content: {},
})
const statesPersonsSchema = new Schema({
profileId:{
type: String,
required: true,
unique: true
},
department: {
type: String,
required: true,
index: true,
},
firstName: String,
lastName: String,
location: String,
org: String,
title: String,
jobDescription: String,
email: {
type: String,
lowercase: true,
},
phoneNumber: String,
activeWork: [activeWorkSchema],
emailList: [String],
jobAssignments: [String],
affiantInfo: {
affiantInfoTitle: String,
affiantInfoExperience: String,
},
assessments: [
{
assessdBy: {
type: Schema.Types.ObjectId,
ref: "statesPerson",
},
dueDate: Date,
questions: {},
},
],
});
export default mongoose.model("statesPersons", statesPersonsSchema);
When I make a query, I get:
Cannot populate path statesPersons.activeWork.referenceId because it is not in your schema. Set the strictPopulate option to false to override.
I don't know if I formatted my populate correctly or if the problem is in my schema,

Save current User into field within array in Mongoose

Here is a relevant part of my Schema, where I'll make reservations to a "space":
var spaceSchema = new mongoose.Schema({
spaceName: String,
scheduledDates: [{
scheduledDates: String,
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
username: String
}
}]
});
Author should be the current user that's logged in. Here is my route to update those fields:
router.put('/:space_id/schedule', function(req, res) {
Space.findByIdAndUpdate(req.params.space_id, {
'$push': { 'scheduledDates': req.body.space, 'author': req.user._id }
}, { "new": true, "upsert": true }, function(err, space) {
if (err) {
console.log(err);
} else {
console.log(req.body.space);
}
});
});
I can't access "author" correctly, because it's inside the array. What can I do to update this array, adding a new date and user to make the reservation?
Thank you
UPDATE
I tried to use "_id" instead of "id" in my property but got the same result. It seems like it's ignoring the "author" field, and only saving "scheduledDates"
So the schema was like this:
scheduledDates: [{
scheduledDates: String,
author: {
_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
username: String
}
}]
And then in my route, I changed what I was 'pushing':
'$push': { 'scheduledDates': req.body.space, 'author._id': req.user._id }
UPDATED 2
Changed the way I was getting the object to push:
'$push': {
'scheduledDates': {
'scheduledDates': req.body.space,
'author': { _id: req.user._id, username: req.user.username }
}
}
Now I'm getting the following error:
message: 'Cast to string failed for value "{ scheduledDates: \'04/11/2017\' }" at path "scheduledDates"',
name: 'CastError',
stringValue: '"{ scheduledDates: \'04/11/2017\' }"',
kind: 'string',
value: [Object],
path: 'scheduledDates',
reason: undefined } } }

Mongoose - insert object with array to mongo DB

I'm using Mongo for the first time and I'm having difficulties with creating a document which has an array.
The object is passed to a nodejs server like so:
{
"customerid":"121212",
"name": "Zero 2679",
"email": "a#a.com",
"address": "bla bla bla",
"tokens":[{"ctoken":"123456"},{"ctoken":"1234567"}]
}
The code executes the following:
var newCustomer = new Customer(
{
_id: request.body.customerid,
name: request.body.name,
email: request.body.email,
address: request.body.address,
tokens:request.body.tokens
});
newCustomer.save(function (err) {
if (err) winston.log('error', err);
// saved!
})
The schema is configured like so:
var customerSchema = new Schema({
// index: true => Tells mongo to index this paramater because it is used frequently. It makes querying faster
_id: {type: String, unique: true}, // unique customer ID
name: {type: String, default: '', required: true}, // Customer name
//email: {type: mongoose.SchemaTypes.Email, required: true},
email: {type: String, required: true},
address: { type: String, required: true },
toknes: [{ ctoken :{type: String} }]
}, {collection: 'customers'});
When I go and look at the object in the MongoDB, it looks like this:
{
"_id": "121212",
"email": "a#a.com",
"address": "bla bla bla",
"tokens": [],
"name": "Zero 2679",
"__v": 0
}
The tokens are missing and there's a '_v' value which I don't even have.
Please advise what am I doing wrong?
in your schema
tokens: [{ ctoken : String }]
request.body.tokens must be something like = {ctoken: 'some string'}
var newCustomer = new Customer(
{
_id: request.body.customerid,
name: request.body.name,
email: request.body.email,
address: request.body.address,
tokens:[request.body.tokens]
});
newCustomer.save(function (err) {
if (err) winston.log('error', err);
// saved!
})
and if the customer db documents contains data, then you should perform push operation
In your schema it should be:
tokens: [{ type: String }]
As ctoken is not a data type. The working schema is illustrated below:
var customerSchema = new Schema({
_id: {type: String, unique: true},
name: {type: String, default: '', required: true},
email: {type: String, required: true},
address: { type: String, required: true },
tokens: [{ type: String }]
}, {collection: 'customers'});

Insert new values in array in mongoose

Below code contains two schema now Grocery Schema contains array of users in which i want to store all users id which are related to itemName
I have no clue how to insert new values in mongodb
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var GrocerySchema= new Schema({
itemName: {
type: String,
required: true,
unique: true
},
completed: Boolean,
date: String,
users:[{user_id:{type:Schema.Types.ObjectId,ref:user}}]
});
grocerydata=mongoose.model('grocery',GrocerySchema);
var UserSchema = new Schema({
fname: {
type:String,
required:true
},
lname:{type:String},
email: {
type: String,
unique: true,
required: true
},
password: {
type: String,
required: true
}
});
module.exports = mongoose.model('User', UserSchema);
I have used below code for saving the multiple values and set the value of array
var docs= {
itemName : req.body.item,
completed: true,
date: new Date(),
$push: {"users": {user_id: req.body._id}}
}
}
grocerydata.create(docs, function(err, results) {
if (err)
res.send(err);
console.log(results);
});
but I am not able to push the user_id in Grocery Please help me
Thanks in Advance!!
You have an error in your last snippet of code. var docs should be the following:
var docs={
itemName : req.body.item,
completed: true,
date: new Date(),
//you forgot to wrap $push in {}
{$push: {"users": {user_id: req.body._id}}}
}
Source

How to push to an array in mongoose

I have this code:
router.post('/setsuggestions', function(req, res, next){
if(!req.body.username || !req.body.challengessuggestions){
return res.status(400).json({message: challengessuggestions});
}
var query = { username: req.body.username };
/*User.findOneAndUpdate(query, { challengessuggestions: req.body.challengessuggestions }, callback = function(response){
res.json(response);
});*/
/*
User.findOneAndUpdate(
query,
{$push: {"challengessuggestions": {$oid: req.body.challengessuggestions}}},
callback = function(response) {
res.json(response);
}
);*/
User.findOneAndUpdate(
query,
{$push: {challengessuggestions: req.body.challengessuggestions}},
{safe: true, upsert: true},
function(err, model) {
res.json(err);
}
);
});
When I postman like this:
I get the following error:
{ "name": "MongoError", "message": "exception: The field
'challengessuggestions' must be an array but is of type OID in
document {_id: ObjectId('56263b910d1a2f1f0077ffae')}", "errmsg":
"exception: The field 'challengessuggestions' must be an array but is
of type OID in document {_id: ObjectId('56263b910d1a2f1f0077ffae')}",
"code": 16837, "ok": 0 }
This is the schema definition of AppUser:
var UserSchema = new mongoose.Schema({
username: { type: String, lowercase: true, unique: true },
firstname: { type: String},
lastname: { type: String},
difficulty: { type: String},
isstudent: { type: Boolean },
haschildren: { type: Boolean},
gender: { type: String },
email: { type: String, unique: true},
birthdate: String,
isdoingchallenges: { type: Boolean },
challengescompleted: [{ type: ObjectId, ref: 'Challenge' }],
currentchallenge: { type: ObjectId, ref: 'Challenge' },
challengessuggestions: [{ type: ObjectId, ref: 'Challenge' }],
hash: String,
salt: String
});
This is the schema definiton of challenge:
var Challengeschema = new mongoose.Schema({
name: { type: String, initial: true, required: true, index: true },
image: { type: Array },
difficulty: { type: String },
studentfriendly: { type: Boolean },
childfriendly: { type: Boolean },
description: { type: String }
});
I'm sending this in the function that calls the api:
Object {_id: "5631423f8c5ba50300f2b4f6", difficulty: "medium", name:
"Probeer 1 van onze recepten.", __v: 0, childfriendly: true…}
This gives me following error:
D:\Stijn\Documenten\EVA-project-Groep-6\Api\node_modules\mongoose\lib\schema\obj
ectid.js:134
throw new CastError('ObjectId', value, this.path);
^ Error
at MongooseError.CastError (D:\Stijn\Documenten\EVA-project-Groep-6\Api\node
_modules\mongoose\lib\error\cast.js:18:16)
at ObjectId.cast (D:\Stijn\Documenten\EVA-project-Groep-6\Api\node_modules\m
ongoose\lib\schema\objectid.js:134:13)
at Array.MongooseArray.mixin._cast (D:\Stijn\Documenten\EVA-project-Groep-6\
Api\node_modules\mongoose\lib\types\array.js:124:32)
at Array.MongooseArray.mixin._mapCast (D:\Stijn\Documenten\EVA-project-Groep
-6\Api\node_modules\mongoose\lib\types\array.js:295:17)
at Object.map (native)
at Array.MongooseArray.mixin.push (D:\Stijn\Documenten\EVA-project-Groep-6\A
pi\node_modules\mongoose\lib\types\array.js:308:25)
at Query. (D:\Stijn\Documenten\EVA-project-Groep-6\Api\routes\ind ex.js:144:44)
at D:\Stijn\Documenten\EVA-project-Groep-6\Api\node_modules\mongoose\node_mo
dules\kareem\index.js:177:19
at D:\Stijn\Documenten\EVA-project-Groep-6\Api\node_modules\mongoose\node_mo
dules\kareem\index.js:109:16
at doNTCallback0 (node.js:408:9)
at process._tickCallback (node.js:337:13) 29 Oct 22:05:38 - [nodemon] app crashed - waiting for file changes before starti ng...
How do I solve this?
Query the User user using findOne() first and use the first found document that's passed to the callback to save the embedded documents with:
router.post('/setsuggestions', function(req, res, next){
if(!req.body.username || !req.body.challengessuggestions){
return res.status(400).json({message: challengessuggestions});
}
var query = { username: req.body.username };
User.findOne(query, function (err, user){
if (err) //throw ...
if (user) {
if (user.challengessuggestions && user.challengessuggestions.length) {
user.challengessuggestions.push(req.body.challengessuggestions);
}
else {
user.challengessuggestions = [req.body.challengessuggestions];
}
// save changes
user.save(function (err) {
if (!err) {
// done ...
}
});
}
});
);

Resources