how to make primary key / _id optional to input in mongoose - angularjs

I want make primary key no need to input but primary key auto generate in mongodb.
so, i use {type : ObjectId,required:false}, but it wont work because I let the primary key empty. so is there another ways to make pprimary key optional to input? Thankyou
rest api model
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId
var accessmenu = new Schema({
_id : {type : ObjectId,required: false},
acc_id : String,
name : String,
read : Boolean,
execute : Boolean
},{ collection: 'access_menu'});
var accessmenu = mongoose.model("accessmenu",accessmenu);
module.exports.accessmenu = accessmenu;
rest api
app.put("/access_menu/:id",function(req,res){
var AccessMenu = new accessmenu({
_id : req.body._id,
acc_id : req.body.acc_id,
name : req.body.name,
read : req.body.read,
execute : req.body.execute
});
AccessMenu.save(function(err){
if(err)
{
accessmenu.update({_id : req.params.id},{$set:{acc_id : req.body.acc_id,
name : req.body.name,
read : req.body.read,
execute : req.body.execute
}},function(err,users){
if(err)
{
data['error'] = 1;
data['Access_Menu'] = "update faill";
res.json(data);
}
else
{
data['error'] = 0;
data['Access_Menu'] = "update success";
res.json(data);
}
});
}
else
{
data['error'] = 0;
data['Access_Menu'] = "input success";
res.json(data);
}
});
});
script.js
if($scope.data_acc_lv.length > 0)
{
for(var i = 0;i<$scope.data_acc_lv.length;i++)
{
var input3 = {
"_id" : $scope.data_acc_lv[i]._id,
"acc_id":$scope.accLvID,
"name": $scope.data_acc_lv[i].name,
"read": $scope.data_acc_lv[i].read,
"execute": $scope.data_acc_lv[i].execute
}
$http.put("http://localhost:22345/access_menu/" + $scope.data_acc_lv[i]._id,input3)
.success(function(res,err){
if(res.error == 0)
{
$scope.data_acc_lv.length = 0;
}
else
{
console.log(err);
}
});
}
}

Mongoose assigns each of your schemas an _id field by default if one is not passed into the Schema constructor. The type assigned is an ObjectId to coincide with MongoDB's default behavior.
If you don't want an _id added to your child schema at all, you may disable it using this option.
// disabled _id
var childSchema = new Schema({ name: String }, { _id: false });
var parentSchema = new Schema({ children: [childSchema] });
You can only use this option on sub-documents. Mongoose can't save a document without knowing its id, so you will get an error if you try to save a document without an _id.
http://mongoosejs.com/docs/guide.html

Related

PUSH id in order like add to cart

I created model schema for users and products with simple CRUD, my next project is my model schema order where I push my userId and projectId in the array in order.
this is the code that I created in the controller
module.exports.makeOrders = (reqBody) => {
let newOrder = new Order({
totalAmount : reqBody.totalAmount,
usersOrder.push({
userId : reqBody.userId,
project : reqBody.projectId
}),
})
return newOrder.save().then((order, error) =>{
if(error){
return false;
}
else{
return true;
}
})
}
and this is my route
router.post("/checkout", (req, res) => {
let data = {
userId : req.body.userId,
productId : req.body.productId
}
userController.makeOrders(data).then(resultFromController => res.send(resultFromController))
})
this is my model
const orderSchema = new mongoose.Schema({
totalAmount : {
type : Number,
required : true
},
purchasedOn : {
type : Date,
default : new Date
},
usersOrder :[
{
userId : {
type : String,
required : true
},
productId : {
type : String,
required : true
},
}
]
})
this is what I enter in postman
{
"totalAmount" : 1000,
"userId" : "62a9c46c4d15dc8157c375aa",
"productId" : "62aafe01d9337ce87ff5aaa1"
}
the error that I'm experiencing is "SyntaxError: Unexpected token '.' "
based on what I know I put the push method in the wrong place. I just copy the create method in the user which is working. I don't know why it is not working in order controller.
Note. I just started to learn json.
You have to update your routes like this as you are missing the totalAmount field and inside your schema you mentioned it as required fields.
router.post("/checkout", (req, res) => {
let data = {
userId : req.body.userId,
productId : req.body.productId,
totalAmount: req.body.totalAmount
}
userController.makeOrders(data).then(resultFromController => res.send(resultFromController))
})

Query over an array in mongoose returns empty array

I've a Menu model which has a list of members(roles) who can access it.When I try to query based on role, mongoose returns empty array. I created and populated Menu collection in mongoose terminal before creating the schema. When I execute the query in terminal it returns right records.Please help.
const MenuSchema = mongoose.Schema({
menuId:{type:Number},
menuName:{type:String},
path:{type:String},
accessTo:[{type:String}]
});
const Menu = module.exports = mongoose.model('Menu', MenuSchema);
module.exports.getMenuByRole = function(role, callback){
console.log('rle'+role);
const query = {"accessTo": role};
Menu.find(query,callback);
// Menu.find(query, callback);
}
Here is the result of execution in terminal:
db.Menu.find({"accessTo":"admin"})
{ "_id" : ObjectId("5d352f6c866e313fca373d1d"), "menuId" : 2, "menuName" : "Profile", "path" : "/profile", "accessTo" : [ "admin", "employees", "user" ] }
{ "_id" : ObjectId("5d352f73866e313fca373d1e"), "menuId" : 3, "menuName" : "Employees", "path" : "/employess", "accessTo" : [ "admin" ] }
You have to use .exec() with find.
And, accessTo is an array field you have to use $in, with it.
const mongoose = require("mongoose")
const Schema = mongoose.Schema
mongoose.connect('mongodb://localhost:27017/stackoverflow', {useNewUrlParser: true});
const MenuSchema = new Schema({
menuId:{type:Number},
menuName:{type:String},
path:{type:String},
accessTo:[{type:String}]
});
const menuModel = mongoose.model("Menu", MenuSchema)
function run(role){
menuModel
.find({
accessTo: {
$in: [role]
}
})
.exec((err, result) => {
console.log("result", result)
}, err => {
console.log("err", err)
})
}
run("admin")

Mongoose stops to $push to array if the field already exists in a document

I am using Node and Mongoose, and trying to set an array of ISODate elements:
"visitLog" : [
ISODate("2017-10-22T22:43:49.571Z"),
ISODate("2017-10-22T22:44:39.572Z"),
ISODate("2017-10-22T23:35:36.111Z"),
ISODate("2017-10-22T23:48:26.516Z"),
ISODate("2017-10-22T23:50:33.378Z"),
ISODate("2017-10-22T23:53:56.227Z"),
ISODate("2017-10-22T23:57:20.986Z")
]
So I had an existing schema where visitLog field did not existed, added new field to a schema - visitLog: [ {type: Date, default: '' }],and it worked - the result is what you see above.
But when I created a new document with updated schema that already has an empty array in it - "visitLog" : [ ] , $push just stopped working.
Here is mongoose query, if needed:
// conditions is a ternary operator that checks whether req.body username
// is an email or not, and puts needed condition to a query
var conditions = (!/^[a-zA-Z0-9\-\_\.\+]+#[a-zA-Z0-9\-\_\.]+\.[a-zA-Z0-9\-\_]+$/.test(req.body.username)) ? ' {email: req.body.username } ' : ' {username: req.body.username } ';
var fieldsToSet = {
$push: {
visitLog: new Date().toISOString(),
}
};
var options = { upsert: true };
User.findOneAndUpdate(conditions, fieldsToSet, options, function(err, user) { ...
The working document was created in mongo console, while the second was generated on a server, but I can't how can this make any difference.
Using $push shuld work with empty arrays. Can someone explain what's wrong here?
Thank you.
Edit
It figures that using findByIdAndUpdate without conditions works for both documents:
var fieldsToSet = {
$push: {
visitLog: new Date().toISOString(),
}
};
var options = { new: true };
req.app.db.models.User
.findByIdAndUpdate(req.user.id, fieldsToSet, options, function(err, user) {
You can do with the following query.
User.findOne(condiitons, (err, user) => {
if (user) {
var date = new Date().toISOString();
user.visitLog.push(date);
user.save();
...
}
});

Can't get Firebase reference to ID to define current user

I think I am getting my keys, arrays, values and IDs mixed up here but can't seem to figure it out.
I want a way to get the current user in a ProfileCtrl controller. This is my current implementation using promises, $waitForAuth and once. But I am not sure if implementing currently.
var user = "";
var key = "";
var uids = Users.allUIDs();
console.log(uids);
Auth.$waitForAuth().then(function () {
var uid = Auth.$getAuth().uid;
console.log(uid);
for (var i = 0; i < uids.length; i++) {
console.log(uids[i].value().toString());
if (uids[i].value() == uid) {
var userKeyRef = new Firebase(firebaseUrl + uids + uids[i]);
userKeyRef.once('value').then(function(snapshot) {
key = snapshot.val();
}).then(function(){
user = new Firebase(firebaseUrl + users).child(key).val();
});
console.log(user);
console.log('User exists')
break;
}
}
$scope.user =user;
}).catch(function (error) {
console.log(error);
})
I do a check of the uids in an array, and if they match the authenticated user, I get the key from within the uids array and use that key to find the user object in the users array. Here is my database:
{
"uids" : {
"7d34fb85-813c-4586-857e-f062aed67f32" : {
"-KDQDk5vwJXmFngwI7iQ" : {
"registered" : true
}
}
},
"users" : {
"-KDQDk5vwJXmFngwI7iQ" : {
"email" : "random#gmail.com",
"firstname" : "Random",
"lastname" : "Person",
"uid" : "7d34fb85-813c-4586-857e-f062aed67f32"
}
}
}
For a clearer example, when I console.log the uids as it is returned from my service, it looks like:
Which means the uids are coming through?
Here is my code to get the uids:
app.factory('Users', ['$firebaseArray','$firebaseObject', 'Auth', function ($firebaseArray, $firebaseObject, Auth) {
var ref = new Firebase("https://urlformyapp.firebaseio.com");
var users = $firebaseArray(ref.child('users'));
var uids = $firebaseArray(ref.child('uids'));
return {
all: function () {
return users;
},
allUIDs: function () {
return uids;
},
get: function (id) {
// Simple index lookup
return users[id];
}
}
}])
Could someone tell me what is going wrong? Why does uids[i].value.toString() not print anything? Is there anything wrong with my code logic given the structure of my DB?

Saving multiple field array in mongodb using mongoose

//Here is model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
// Task schema
var taskSchema = mongoose.Schema({
tasktype : {type: String},
createdon : {type: Date, default: Date.now},
createdby : {type: Schema.Types.ObjectId,ref: 'User'},
visitedby : [{type: Schema.Types.ObjectId,ref: 'User'}],
taskinfo : [{ isactive:Boolean, taskobject:String, taskdetails:String, iscompleted:Boolean}]
});
module.exports = mongoose.model('Task', taskSchema);
// route
var Task = require ('../models/task');
var User = require ('../models/user');
var config = require ('../../config');
module.exports = function(app, express) {
var api = express.Router();
api.post('/tasks', function (req, res) {
var task = new Task({
// ...
tasktype : req.body.tasktype,
taskinfo : req.body.taskinfo,
});
task.save(function(err){
if(err){
res.send(err);
return;
}
res.json({message:'Task has been created'})
});
return api
}
While all other fields getting saved but the one with array with multiple fields always return blank like "taskinfo : [ ] "
The post method is REST API to post a task into mongoose database, for array with single field everything working fine but array with multiple field is not getting saved, someone please help me here.
Basic help will be fine, just please teach me how to save "multiple field array".
Mongoose doesnot always require subdocument structure and this can be achieved by the above model, please dont advice to use subdocument structure, I want to learn this.
Thank You.
I think if taskinfo has a multiple values and you want to save it as embedded document inside task document. You should have different document of task info. So,you can save like that
var TaskInfoSchema = require("taskInfo.js").TaskInfoSchema
var taskSchema = mongoose.Schema({
tasktype : {type: String},
createdon : {type: Date, default: Date.now},
createdby : {type: Schema.Types.ObjectId,ref: 'User'},
visitedby : [{type: Schema.Types.ObjectId,ref: 'User'}],
taskinfo : [TaskInfoSchema]
});
module.exports = mongoose.model('Task', taskSchema);
And now you will have different document as task info like
var taskInfo = mongoose.Schema({
isactive:{type:Boolean},
taskobject:{type:String},
taskdetails:{type:String},
iscompleted:{type:Boolean}
});
var TaskInfo = mongoose.model('TaskInfo', taskSchema);
module.exports.TaskInfo = TaskInfo
module.exports.TaskInfoSchema = taskSchema
When you will save task document,
Var TaskInfo = new TaskInfo({
isactive:true,
taskobject:"",
taskdetails:"",
iscompleted:true
})
var task = {};
task.tasktype = req.body.tasktype;
you can push it
task.taskinfo = [];
for (var i = 0; i < req.body.taskInfo.length; i++) {
var taskInfo = new TaskInfo(req.body.taskInfo[i]);
task.taskinfo.push(taskInfo);
}
Then you will save task document
var taskObj = new Task(task);
taskObj.save(function (err) {
if (err) {
res.send(err);
return;
}
res.json({
message: 'Task has been created'
})
});
});

Resources