$set and $pull in MongoDb over Same Document - reactjs

i have a product profile, and when i want to edit the product, i would like that the user can, Edit fields in the producto (title, price....), upload a new image, and delete some image. All of this at the same time, in the same operation.
I have this code, that works but not at all.
const producto = await Producto.findByIdAndUpdate(
req.params.id,
{
'$pull': {"images": {"filename": imagesDelete }},
'$set': {title, categoria, subCategoria, price, description, contacto}},
{new: true}
);
with this code i can: upload an image and edit form, upload an image and delete some image. But when i want to upload image, delete image, and edit form. Not works....
Someone can tell why?
Here is the complete code in the editProduct:
exports.editarProductoUser = async (req, res, next) => {
//REVISAR SI HAY ERRORES
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
console.log(req.body);
const { imagesDelete, title, categoria, subCategoria, price, description, contacto } = req.body;
try {
// //REVISAR EL ID
const productoTest = await Producto.findById(req.params.id);
// //SI EL PRODUCTO EXISTE O NO!!!
if (!productoTest) {
console.log("hay un error en edicion");
return res.status(404).json({ msg: "Producto no encontrado" });
}
// // //Verificar el PRODUCTO
if (productoTest.author.toString() !== req.user.id) {
return res.status(401).json({ msg: "No Autorizado para Editar" });
}
if (imagesDelete !== undefined) {
if (typeof imagesDelete === "string") {
cloudinary.uploader.destroy(imagesDelete, function (err, res) {
if (err) {
console.log(err);
return res.status(400).json({
ok: false,
menssage: "Error deleting file",
errors: err,
});
}
console.log(res);
});
} else {
for (let filename of imagesDelete) {
console.log(filename);
cloudinary.uploader.destroy(filename, function (err, res) {
if (err) {
console.log(err);
return res.status(400).json({
ok: false,
menssage: "Error deleting file",
errors: err,
});
}
console.log(res);
});
}
}
}
//ACTUALIZAR PRODUCTO
const producto = await Producto.findByIdAndUpdate(
req.params.id,
{
'$pull': {"images": {"filename": imagesDelete }},
'$set': {title, categoria, subCategoria, price, description, contacto}},
{new: true}
);
const images = req.files.map((f) => ({
url: f.path,
filename: f.filename,
}));
//if(producto.images === undefined) return null;
producto.images.push(...images);
console.log(producto.images);
await producto.save();
res.json({ producto });
} catch (error) {
console.log(error);
res.status(500).send("Hubo un Error");
}
};
Here a snapshot of the form, to see the fields:

$pull and $set
db.collection.update({
_id: "123"
},
{
"$pull": {
images: {
filename: "123"
}
},
"$set": {
title: "banana",
categoria: "b",
price: 200
}
})
mongoplayground
nodejs mongoose
let query = {
_id: "123"
};
let update = {
"$pull": {
"images": {
"filename": "123"
}
},
"$set": {
"title": "banana",
"categoria": "b",
"price": 200
}
};
Producto.updateOne(
query,
update,
function(err, result) {
if (err) {
...
} else {
...
}
}
);

Related

error: ReferenceError: interaction is not defined

I'm trying to add more than one into this switch thing, it works with one, but adding more just adds gets me this error "interaction is not defined"
game1 & network is querying to
const { game1db, networkdb} = require('../mysql/mysqlquery.js')
How do I solve this "interaction is not defined", I'd be grateful for all the help
Code:
const run = async (client, interaction) => {
if (!interaction.guild) return;
let platform = interaction.options.get('platform').value
let username = interaction.options.getString("username")
console.log(platform)
const hasRole = interaction.member.roles.cache.some(r => r.name === "Support")
if (!hasRole) return;
await interaction.deferReply({ ephemeral: true });
await wait(4000);
switch (platform) {
case "network":
try {
networkdb(`${username}`, (err, result) => {
if (err) {
interaction.followUp({ content: result, ephemeral: true });
} else {
interaction.followUp({ content: result, ephemeral: true });
}
})
} catch (error) {
interaction.followUp({ content: `error: ${error}`, ephemeral: true });
}
break;
case "game1":
try {
game1db(`${username}`, (err, result) => {
if (err) {
interaction.followUp({ content: result, ephemeral: true });
} else {
interaction.followUp({ content: result, ephemeral: true });
}
})
} catch (error) {
interaction.followUp({ content: `error: ${error}`, ephemeral: true });
}
break;
default:
interaction.followUp({ content: `${platform} is not supported yet`, ephemeral: true });
}
}

Discord: I need a filter to make a select menu with author id but its keeps saying is "properties of undefined (reading 'author')"

//I need only 1 use of select menu
const { MessageEmbed, MessageAttachment, Message } = require('discord.js');
module.exports = {
name: 'interactionCreate',
async execute(interaction, client, message) {
if (interaction.isCommand()) {
const command = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction, client);
} catch (error) {
console.error(error);
await interaction.reply({
content: 'There was an error while executing this command!',
ephemeral: true
});
}
} else if (interaction.isSelectMenu()) {
const i = `${interaction.user.id}`
console.log(i)
const g = `${message.author.id}`
console.log(g)
if (interaction.customId == "color-select") {
let colores = "";
await interaction.values.forEach(async value =>{
colores += `${value} `
});
const filter = (interaction) => {
i === g;
};
const collector = interaction.channel.createMessageCollector({ filter, time: 15000 });
await interaction.reply({ content: `Wow tu color favorito es: ${colores} `});
}
}
},
};
//error
TypeError: Cannot read properties of undefined (reading 'author')

How to download data as Excel (.xslx) in Nextjs

I want to add a "Download as Excel" button to my Nextj application, by using any library to simplify the development or adding a component to my project; I already tried these but had issues with both of them:
https://www.npmjs.com/package/react-html-table-to-excel
This Downloads data with '.xls' file extension so opening them with excel throws a warning. I tried to edit the source code and change file extension to '.xlsx' but this makes the output file corrupted.
https://www.npmjs.com/package/react-export-excel
this works fine with react-create-app but can't make it work in Nextjs due to it's custom webpack configuration. I can't make this part working in Nextjs
///webpack.config.js
vendor: [
.....
'xlsx',
'file-saver'
],
.....
node: {fs: 'empty'},
externals: [
{'./cptable': 'var cptable'},
{'./jszip': 'jszip'}
]
Thanks in advance for any guide!
here is my code as a a sample i hope it helps
/api/shipments/downloadManifest.js/
const fs = require("fs");
import Shipment from "../../../backend/shipmentModel";
const json2xls = require("json2xls");
import path from "path";
const handler = async (req, res) => {
if (req.method === "POST") {
const { batchStart, batchEnd } = req.body;
if (!batchStart || !batchEnd) {
return res.status(200).json({
status: "error",
error: "No start and end date defined!",
});
}
try {
const data = await Shipment.find({
createdAt: {
$gte: batchStart,
$lte: batchEnd,
},
});
const excel = json2xls(data, {
fields: [
"name",
"destination",
"weight",
"carton",
"dollar_rate",
"customs_rate",
"freight_rate",
"freight_$",
"freight",
"customs",
"amountDue",
"mobile",
"action",
],
});
await fs.writeFileSync("./public/manifest.xlsx", excel, "binary");
const filePath = path.join(process.cwd(), "/public/manifest.xlsx");
const manifestBuffer = fs.createReadStream(filePath);
await new Promise(function (resolve) {
res.setHeader(
"Content-Disposition",
"attachment; filename=manifest.xlsx"
);
res.setHeader(
"Content-Type",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
);
res.setHeader("Content-Length", `${manifestBuffer.size}`);
manifestBuffer.pipe(res);
manifestBuffer.on("end", resolve);
manifestBuffer.on("error", function (err) {
if (err.code === "ENOENT") {
res.status(400).json({
error: "error",
error: "Sorry we could not find the file you requested!",
});
res.end();
} else {
res.status(500).json({
error: "error",
message: "Sorry, something went wrong!",
});
res.end();
}
});
});
} catch (error) {
console.log(error);
return res.status(200).json({
status: "error",
msg: error.message,
});
}
}
};
export default handler;
/pages/shipments.js
setLoading(true);
const data = await axios.post(
"/api/shipments/downloadManifest",
{
batchStart: batch.batchStart,
batchEnd:
batchIndex ===
batches?.[batches?.length - 1]?.months?.[
batches?.[batches?.length - 1]?.months?.length - 1
]?.batches?.length -
1
? new Date(Date.now())
: batch.batchEnd,
},
{
responseType: "blob",
}
);
const pdfBlob = new Blob([data.data], { type: "application/xlsx" });
setLoading(false);
return saveAs(pdfBlob, "manifest.xlsx");
do not forget to install "file-saver" and "json2xls" npm packages as a dependency

Update specific index of array in MongoDB

I would like to update the shipping property in my MongoDb (CRUD).
Shipping is an array property that contains object[index]. How to update the specific object such as index1 or index2.
This show the shipping property that contains two objects
If I want to update Object only at index 1 on the providerName, how can I do that
exports.updateShpping = (req, res) => {
const {shipping} = req.body;
Shop.findOne({ _id: req.shop._id }, (err, shop) => {
if (!shipping) {
return res.status(400).json({
error: 'shipping is required'
});
} else {
shop.shipping.push(shipping) ;
}
shop.save((err, addShipping) => {
if (err) {
console.log('Shipping ADD ERROR', err);
return res.status(400).json({
error: 'Shipping add failed'
});
}
res.json(addShipping);
});
});exports.updateShpping = (req, res) => {
const {shipping} = req.body;
Shop.findOne({ _id: req.shop._id }, (err, shop) => {
if (!shipping) {
return res.status(400).json({
error: 'shipping is required'
});
} else {
shop.shipping.push(shipping) ;
}
shop.save((err, addShipping) => {
if (err) {
console.log('Shipping ADD ERROR', err);
return res.status(400).json({
error: 'Shipping add failed'
});
}
res.json(addShipping);
});
});
};

Render template after fetching data from mongodb

app.get('/clients', (req, res) => {
var clientArray;
MongoClient.connect('mongodb://localhost:27017/Clients', (err, db) => {
if (err) {
return console.log('Unable to Connect');
}
console.log('Connected to Mongodb server');
db.collection('Clients').find().toArray().then((docs) => {
clientArray = JSON.stringify(docs, undefined, 2);
// clientArray = docs;
console.log(clientArray);
}, (err) => {
console.log("ERROR")
});
db.close();
});
res.render('clients.hbs', {
infoArray: clientArray,
name: 'Harshit'
});
});
Here the res.render function is being called before getting the required data from the mongodb database. I want to pass the data fetched as an array to the handlebars template.
{{#each infoArray}}
<h1>{{this.name}}</h1>
{{this.region}}
{{/each}}
Here I am trying to go through the array rendered and display the data.Any Help is appreciated.
Structure of array
[{
"name": "harshit",
"region": "delhi"
},
{
"name": "mendax",
"region": "ecuador"
}
]
Render has to be in callback function :
app.get('/clients', (req, res) => {
var clientArray;
MongoClient.connect('mongodb://localhost:27017/Clients', (err, db) => {
if (err) {
return console.log('Unable to Connect');
}
console.log('Connected to Mongodb server');
db.collection('Clients').find().toArray().then((docs) => {
clientArray = JSON.stringify(docs, undefined, 2);
// clientArray = docs;
console.log(clientArray);
db.close();
res.render('clients.hbs', {
infoArray: clientArray,
name: 'Harshit'
});
}, (err) => {
console.log("ERROR")
db.close();
});
});
});
You are almost there.
This is happening becuse MongoClient.connect(.. is asynchronous. So you res.render executes before that.
What you need is, just move your res.render inside that block
app.get('/clients', (req, res) => {
var clientArray;
MongoClient.connect('mongodb://localhost:27017/Clients', (err, db) => {
if (err) {
return console.log('Unable to Connect');
}
console.log('Connected to Mongodb server');
db.collection('Clients').find().toArray().then((docs) => {
clientArray = JSON.stringify(docs, undefined, 2);
// clientArray = docs;
res.render('clients.hbs', {
infoArray: clientArray,
name: 'Harshit'
});
}, (err) => {
console.log("ERROR")
});
db.close();
});
});

Resources