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
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 });
}
}
//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')
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
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);
});
});
};
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();
});
});