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))
})
Related
I have entered the code right, and it worked too. But now i dont know why i am getting same error on different lines of code each time i test. The error comes at the chained commands.
Sometimes its a chained Cy.find commands while sometimes its some other chained command.
::EDIT::
I have changed the code a bit tried doing different methods etc, but still getting the same error. So the code below(Code-1) is the cypress commands to execute the integration test. Since this particular test values might change so I made another file to pass all those values as a single object(Code-2).
FYI the code worked first time, when i didn't have Code-2, ie: when i manually inserted all those values.
Code-1:
/* eslint-disable no-undef */
import { cropFileName, testData } from '../test_case/quoteGen'
describe('waste-Quote-Generation-for-Permanant-Client', () => {
beforeEach(() => {
cy.visit('/login');
});
it('user login', () => {
// login
cy.findByPlaceholderText(/username/i).type(testData.username)
cy.findByPlaceholderText(/password/i).type(testData.pass)
cy.get('.newLoginPanelBtn').click();
// navigate to 'Sales' tab.
cy.findByRole('link', {
name: /sales/i,
timeout: 5000
})
.should('be.visible')
.click({ force : true });
// Click on 'Generate Quote'
cy.findByRole('link', {
name: /generate quote/i,
timeout: 5000
}).click({ force : true })
// cy.wait(3000)
// Select Template
cy.findByRole('link', {
name: /template/i,
timeout: 5000
})
.should('be.visible')
.click({ force : true })
// Select Client
if(testData.clientType!=='create')
cy.findByText(testData.client).click()
else{
cy.get('#newSiteName').click();
cy.get('#newSiteName').type(testData.client);
cy.get('#newSiteEmail').click();
cy.get('#newSiteEmail').type(testData.clientEmail);
cy.get('#createNewSite').click();
cy.wait(200);
cy.findByText(testData.client).click()
}
// Choose Type of Waste
if(testData.wasteTypeOpt.newName!==null){
cy.findByText(testData.wasteTypeOpt.name).click()
cy.get('#towAddNewBtn').click();
}else{
cy.findByText(testData.wasteTypeOpt.name).click()
cy.get('#towContinueBtn').click();
}
// Check if Job Card Exist
if(testData.jobCard.new){
cy.findByText(/create job card/i).click();
// Add Job Card and Verify Job Card
cy.get('.jobCardDiv1 .jobCardDivInpContentDiv:nth-child(6) .jobCardDivInp').click();
cy.get('.jobCardDiv1 .jobCardDivInpContentDiv:nth-child(6) .jobCardDivInp').type('1234');
cy.get('#jobCardDate > span:nth-child(2)').click();
cy.get('.MuiButton-textPrimary:nth-child(2) > .MuiButton-label').click();
cy.get('.newJobCardBtnActive').click({ force : true });
}
cy.get('#job-cards-list > div:first').click();
cy.get('.newJobCardBtnActive').click({ force : true })
// Select Attachments
cy.get('#attach-file-list').children().each((_,index, collection) => {
if(index!==3 && testData.attachments.includes(index))
collection.eq(index).click()
})
cy.get('#attach-file-list').children().findByText(cropFileName('safety attachments',25,5,5)).click()
setTimeout(() => {
cy.findByText(/add to attachment/i).click();
}, 3000);
cy.get('#quoteEditorButton').click();
// Click on 'Quote'
cy.get('#updateScopeOfWorkButton').click();
cy.get('#editTableEditorModal').find('tr').eq(0).then(tbrow => {
testData.scopeofWork.map((el, k) => {
cy.wrap(tbrow).findAllByPlaceholderText('Description').dblclick()
cy.wrap(tbrow).findAllByPlaceholderText('Description').type(el.descp)
cy.wrap(tbrow).find('.navbar-button').click();
cy.findAllByText(el.tow).click()
cy.wrap(tbrow).findByPlaceholderText('volume').dblclick()
cy.wrap(tbrow).findByPlaceholderText('volume').type(el.vol)
cy.wrap(tbrow).findByPlaceholderText('Unit').dblclick()
cy.wrap(tbrow).findByPlaceholderText('Unit').type(el.unit)
cy.wrap(tbrow).findByPlaceholderText('pricing').dblclick()
cy.wrap(tbrow).findByPlaceholderText('pricing').type(el.pricing)
if(k<testData.scopeofWork.length-1)
cy.get('#addNewRowScopeOfWork').click()
return 0
})
})
cy.get('#updateTableModalButton').click();
cy.get('#continueGNRTQT').click()
// Insert mail id, Click on Generate Quote.
cy.get('.quote-cnrf-to-layout:nth-child(2) .quote-cnrf-emails-input').click();
cy.get('.quote-cnrf-to-layout:nth-child(2) .quote-cnrf-emails-input').type(testData.email);
cy.get('.quote-cnrf-to-layout:nth-child(3) .quote-cnrf-emails-input').click();
cy.get('.quote-cnrf-emails-input:nth-child(2)').click();
cy.get('.quote-cnrf-emails-input:nth-child(2)').type('asdf');
cy.get('.quote-cnrf-emails-textarea').click();
cy.get('.quote-cnrf-emails-textarea').type('asdf');
if(testData.sendType)
cy.get('#generateandsend').click();
else
cy.get('#approvedQuote').click();
cy.get('.swal2-confirm').click();
})
})
Code 2:
export const testData = {
username : 'Tester',
pass : '##tester001',
tabType : "",
template : /template/i,
clientType : 'permanent', // permanent, temporary, create
client : /geolocated site/i,
clientEmail : null,
wasteTypeOpt: {
name : /dilution pit/i,
newName : null, },
jobCard : {
new : false,
},
attachments : [],
scopeofWork : [
{ descp : 'asdf',
tow : /grease/i,
vol : '10',
unit : '5',
pricing : '2'
}
],
email : 'asdf#asdf.com',
sendType : true // true => 'Generate and send', false => 'Approved Quote'
}
export const cropFileName = (str, len, frnt, lst) => {
RegExp.escape = function(string) {
return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&')
};
let lastIndx = str ? str.length : 0
if(lastIndx <= len){
return new RegExp(str, "i")
}
else{
console.log('NewREgExp=>',new RegExp(RegExp.escape(str.substring(0,frnt)+'...'+str.substring(lastIndx-lst,lastIndx))))
return new RegExp(RegExp.escape(str.substring(0,frnt)+'...'+str.substring(lastIndx-lst,lastIndx)))
}
}
// ENCASE STRING in CASE INSENSITIVE \i
The 'cropFileName' function is used to manage all those long names. The long names will be snipped in CSS or JS by frontend, 'cropFileName' helps to determine the length of the string and decide whether to add '.' in between the string for RegEx conversion.
I am trying to sort orders in descending and start after on particular key but its not working
nextAfter : -Mk4-n5BnVpwhum62n2g or any Key / _id
db record:
{
'-Mk4-n5BnVpwhum62n2g': {
_id: '-Mk4-n5BnVpwhum62n2g',
createdAt: -1632171667626,
name: 'abc'
},
'-Mk40Ko9DbSeMdjIpY4': {
_id: '-Mk40Ko9DbSeMdjIpY4',
createdAt: -1632171809831,
name: 'new '
}
}
trying query :
query = dbRef.orderByChild('createdAt').startAfter(nextAfter).limitToFirst(limit);
The startAfter() method accepts two parameters - the first is the relevant orderBy value and the second is the optional key of the last entry (for when multiple entries have the same value for the orderBy criteria). So to correctly paginate the reference, you need to pass the previous entry's createdAt value and its key.
const baseQuery = dbRef
.orderByChild('createdAt')
.limitToFirst(limit);
let pageCount = 0, lastChildOnPage = undefined;
const children = [];
while (true) {
const pageQuery = pageCount === 0
? baseQuery
: baseQuery
.startAfter(lastChildOnPage.createdAt, lastChildOnPage.key);
const pageSnapshot = await pageQuery.once('value');
pageSnapshot.forEach((childSnapshot) => {
children.push({ key: childSnapshot.key, ...childSnapshot.val() });
})
const newLastChildOnPage = children[children.length-1];
if (lastChildOnPage !== newLastChildOnPage) {
lastChildOnPage = newLastChildOnPage;
pageCount++;
} else {
break; // no more data
}
}
console.log(`Grabbed ${pageCount} page(s) of data, retrieving ${children.length} children`);
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")
in my company schema i have a posted job which is type array and will hold subdocuments
companySchema.js
PostedJobs : [{
JobName : { type: String, required : true},
JobType : { type: String, required : true},
JobLocation : { type: String, required : true},
JobSalay: { type: String, required : true}
}],
in my /company route i get all company registered by specific user through Creatorentity in model
to get that user company i use
router.get('/', isLoggedIn , function(req, res, next) {
Company.find({'Creator': req.user.id}).then(function(companies) {
res.render('Company', { "Companies" : companies });
});
});
after getting company i want to visit a specific company page on clicking company name(unique)
router.get('/:name' , isLoggedIn , function(req , res , next) {
var name = req.params.name;
Company.findOne({Name : name}).then(function(Company) {
res.render('dashboard',{
"Company" : Company,
errors : []
});
})
});
now i want to post a job to this specific company from a POST route as
my req.body consist of JobName , JobType , JobLocation and JobSalary which i have assigned to a specific variable now how should i push this doc to array
POST route
router.post('/:name' , isLoggedIn , function(req , res , next) {
var JobName = req.body.JobName;
var JobType = req.body.JobType;
var JobLocation = req.body.JobLocation;
var Salary = req.body.Salary;
//push this job to that specific comapny
});
I don't know the schema of your company, but if you want to add PostedJobs to the companies, you should define an array field in it.
router.post('/:name' , isLoggedIn , function(req , res , next) {
var JobName = req.body.JobName;
var JobType = req.body.JobType;
var JobLocation = req.body.JobLocation;
var Salary = req.body.Salary;
//push this job to that specific comapny
// create the postedJob object
var postedJob = {JobName : JobName, JobType : JobType, JobLocation : JobLocation, JobSalay:Salary};
// find the company in DB and add the postedJob to its array of postedJobs
var name = req.params.name;
Company.findOne({Name : name}).then(function(company) {
//modify and save the object received via callback
company.postedJobs.push(postedJob);
company.save();
});
});
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