so I'm having a really hard time getting the document to save to the database in the case where the product already exists in the cart. I am able to target the item from the database, make changes to it and console output the correct values but in this particular case it wont save the result to the Database. I've tried rewriting it using the updateOne() function and I had little luck. I could really use the help i'm super stuck on this probem. Pics for more info: Block of code that's not working, console output that reflects desired change, mongoDB document that the changes will not save to.
If anyone could point me in the right direction I would greatly appreciate it.
router.post('/add-to-cart',[
auth,
check('productId','productId is required').not().isEmpty(),
check('quantity', 'quantity is required').not().isEmpty()
] , async (req,res) => {
//checks field validation
const errors = validationResult(req);
if(!errors.isEmpty()){
res.status(400).json({errors:errors.array()});
};
//Takes token from the header
const token = req.header('x-auth-token');
if (!token){
return res.status(401).json({ msg: 'no token, auth denied'});
}
//decode token and find associated user
const decoded = jwt.verify(token, config.get('jwtSecret'));
let userPayload = decoded.user;
//build cart object
try{
//populate from request body
const {productId, quantity} = req.body;
//find User using the payload
let user = await User.findById(userPayload.id);
//get the product from db
let product = await Product.findById(productId);
//calculate price of item(s) added to cart
let total = ( quantity * product.price);
//create cart object
//Check to see if cart already exists
let iscart = await Cart.findOne({user:user});
//there is an existing cart
*if(iscart){
let found = false;
for (i=0;i<iscart.orderItems.length;i++)
{
if(iscart.orderItems[i].product._id.toString() == product._id.toString()){
found=true;
console.log('found that product!');
iscart.orderItems[i].qty += quantity;
try{
await iscart.save();
console.log(iscart);
}
catch(err){
console.error(err);
res.status(500).send('server error');
}
res.status(200).send(iscart.orderItems[i]);
break;
}*
}
if(!found){
await Cart.updateOne(
{user:iscart.user},
{$push:{orderItems:
{
product:product,
qty:quantity,
total:total
}}
}
)
res.status(200).send('product pushed to orderItems')
}
}
//there isnt an existing cart so we create one
else{
const cart = new Cart({
user,
orderItems:
{ product:product,
qty:quantity,
total:total
}
})
await cart.save();
res.status(200).send('cart created and saved');
}
}
catch(err){
console.error(err);
res.status(500).send('server error');
}
})
Figured it out!! When you are updating a nested object inside of a document you have to mark the object as modified so it knows to update it. this line fixed my issue:
iscart.markModified('orderItems');
Related
We are trying to read a document file from Firestore through Dialogflow. We get as far as "I can't find your reservation." Each document's id is auto generated, so we can't match from the Document ID field (or at least do not know how to). Any help would be greatly appreciated!
Fulfillment function code:
function readReservation(agent) {
let id = agent.parameters.name.toString();
let collectionRef = db.collection('reservations');
let userDoc = collectionRef.doc(id);
return userDoc.get()
.then(doc => {
if (!doc.exists) {
agent.add('I could not find your reservation.');
} else {
db.collection('reservations').doc(id).update({
newname: agent.parameters.newname
}).catch(error => {
console.log('Transaction failure:', error);
return Promise.reject();
});
agent.add('Ok. I have updated the name on the reservation.');
}
return Promise.resolve();
}).catch(() => {
agent.add('Error reading entry from the Firestore database.');
});
}
I have tried different ways to write this code, but was unsuccessful.
I have connected MongoDB to my discord.js code and have made a setwelcome command as per-server data so that each server can customize their own welcome message. Everything works great, I just want to know if there is any way that I can make the message appear as an embed? Here's the code:
//importing all the needed files and languages
const mongo = require('./mongo')
const command = require('./command')
const welcomeSchema = require('./schemas/welcome-schema')
const mongoose = require('mongoose')
const Discord = require('discord.js')
mongoose.set('useFindAndModify', false);
//my code is inside this export
module.exports = (client) => {
//this next line is for later
const cache = {}
command(client, 'setwelcome', async (message) => {
const { member, channel, content, guild } = message
//checking to see that only admins can do this
if (!member.hasPermissions === 'ADMINISTRATOR') {
channel.send('You do not have the permission to run this command')
return
}
//simplifying commands
let text = content
//this is to store just the command and not the prefix in mongo compass
const split = text.split(' ')
if (split.length < 2) {
channel.send('Please provide a welcome message!')
return
}
split.shift()
text = split.join(' ')
//this is to not fetch from the database after code ran once
cache[guild.id] = [channel.id, text]
//this is to store the code inside mongo compass
await mongo().then(async (mongoose) => {
try {
await welcomeSchema.findOneAndUpdate({
_id: guild.id
}, {
_id: guild.id,
channelId: channel.id,
text,
}, {
upsert: true
})
} finally {
mongoose.connection.close()
}
})
})
//this is to fetch from the database
const onJoin = async (member) => {
const { guild } = member
let data = cache[guild.id]
if (!data) {
console.log('FETCHING FROM DATABASE')
await mongo().then( async (mongoose) => {
try {
const result = await welcomeSchema.findOne({ _id: guild.id })
cache[guild.id] = data = [result.channelId, result.text]
} finally {
mongoose.connection.close()
}
})
}
//this is to simplify into variables
const channelId = data[0]
const text = data[1]
/*this is where the message sends on discord. the second of these 2 lines is what I want embedded
which is basically the welcome message itself*/
const channel = guild.channels.cache.get(channelId)
channel.send(text.replace(/<#>/g, `<#${member.id}>`))
}
//this is to test the command
command(client, 'simjoin', message => {
onJoin(message.member)
})
//this is so the command works when someone joins
client.on('guildMemberAdd', member => {
onJoin(member)
})
}
I know how to usually make an embed, but I'm just confused at the moment on what to put as .setDescription() for the embed.
Please advise.
If you just want to have the message be sent as an embed, create a MessageEmbed and use setDescription() with the description as the only argument. Then send it with channel.send(embed).
const embed = new Discord.MessageEmbed();
embed.setDescription(text.replace(/<#>/g, `<#${member.id}>`));
channel.send(embed);
By the way, if you are confused about how to use a specific method you can always search for the method name on the official discord.js documentation so you don’t have to wait for an answer here. Good luck creating your bot!
For some reason, the function .save() isn't saving my documents on MongoDB. All seem right and the first two registers work and update successfully, but my third register 'specialBanner' doesn't work.
When I console log service it doesn't show as part of the special object, although when I console special.specialBanner it is there.
Has anyone experienced something like this before?
Thanks for your help :)
const updateSpecial = async (req, res, next) => {
const { title, description, specialBanner } = req.body;
let special;
try {
special = await Special.findById(specialId);
} catch (err) {
const error = new HttpError(
"Something went wrong, could not update special.",
500
);
return next(error);
}
if (title) {
special.title = title;
}
if (description) {
special.description = description;
}
if (specialBanner) {
special.specialBanner = specialBanner;
}
try {
//Here if I check 'special I get all the right inputs, but the 'specialBanner'.
special = await special.save();
} catch (err) {
const error = new HttpError(
"Something went wrong, could not update special.",
500
);
return next(error);
}
res.status(200).json({ special: special.toObject({ getters: true }) });
};
I assume you are using mongoose and, Special is a collection.
Replace the line
special = await Special.findById(specialId)
with
special = await Special.findById(specialId).exec()
I'm having difficulty getting data with subscribe in the constructor of an Ionic page, basically I need to do the subscribe to get a list and show to the user, but I get undefinied
In my constructor, I do this:
this.getUser(this.auth.currentUser().uid);
console.log(this.user);
My getUser():
getUser(uid) {
const self = this;
this.auth.getUserData(uid).subscribe(function(doc) {
if (doc.exists) {
self.user = doc.data();
} else {
console.log("No such document!");
}
});
};
But, when i call other function with button, i get the data:
userf(){
console.log(this.user);
}
Obs: I use Firestore
The reason it gives you undefined is because your method “getUser” is async and when you call console.log the user value is not yet obtained.
So you should access user value inside your getUser method after it is received.
Now also you are trying to pass “this” into the getUser method with const. start using fat arrow functions which do not create their own scope (this):
getUser(uid) {
this.auth.getUserData(uid).subscribe((doc) => {
if (doc.exists) {
this.user = doc.data();
} else {
console.log("No such document!");
}
});
};
I have a route set up to receive a webhook from SendGrid, which sends MultiPart/form data. I can get the various fields to output in the console with busboy, but I'm struggling to fill in the final piece of the puzzle: getting this parsed data into a Collection object (or just into MongoDB if not familiar with meteor).
I thought something like the following would work, but the data arrays in the db are always blank, i'm guessing i'm missing a crucial step in knowing when the stream has finished?
WebApp.connectHandlers.use('/applicants', (req, res, next) => {
let body = '';
req.on('data', Meteor.bindEnvironment(function (data) {
body += data;
let bb = new Busboy({ headers: req.headers });
let theEmail = [];
bb.on('field', function(fieldname, val) {
console.log('Field [%s]: value: %j', fieldname, val);
let theObject = [];
theObject[fieldname] = val;
theEmail.push(theObject);
}).on('error', function(err) {
console.error('oops', err);
}).on('finish', Meteor.bindEnvironment(function() {
console.log('Done parsing form!');
// try to add data to database....
Meteor.call('applicants.add', theEmail);
}));
return req.pipe(bb);
}));
req.on('end', Meteor.bindEnvironment(function () {
res.writeHead(200);
res.end();
}));