How to create multiple array of objects in Mongoose? - javascript

can anyone help me how to add multiple "Addons" per create ?
With this code I can add only one addons ..
(Tested in postman) but can anyone suggest me how I can make it to add multiple addons ?
Model
const itemSchema = new mongoose.Schema({
name: {
type:String
},
price:{
type:Boolean
},
addons:[{
addonsName:{
type:String
},
price:{
type:String
}
}]
})
Controller :
const addItem = await Item.create({
name:req.body.name,
price: idOfGroup,
addons:[{addonsName:req.body.addonsName, price: req.body.price}]
});
res.status(200).json({status:'Success',addItem})
I "fix" it doing
const addItem = await Item.create(req.body);
And in postman I write
{
"name":"Test1",
"addons" : [
{
"addonsName":"Test",
"price":"100"
},
{
"addonsName":"TestTest",
"price":"200"
}
]
}
But Is this the wrong way of using .Create() ?

According to your postman sample, you're passing the addons array under the key addons. So just pass that as the addons:
const addItem = await Item.create({
name: req.body.name,
price: idOfGroup,
addons: req.body.addons,
});
res.status(200).json({ status: "Success", addItem });
You could additionally use object destructuring to get rid of the req.body. repetition:
const { name, addons } = req.body;
const addItem = await Item.create({
name,
price: idOfGroup,
addons,
});
res.status(200).json({ status: "Success", addItem });

you can make the addons as Array like below you can see
const itemSchema = new mongoose.Schema({
name: {
type:String
},
price:{
type:Boolean
},
addons:[]
)}
In controller:
const addItem = await Item.create({
name:req.body.name,
price: idOfGroup,
addons:req.body.addons
});
res.status(200).json({status:'Success',addItem})
Postman request payload:
{
"name":"Test1",
"addons" : [
{
"addonsName":"Test",
"price":"100"
},
{
"addonsName":"TestTest",
"price":"200"
}
]
}

Related

How to set a policy/flag to stop a product from selling when out of stock

I'm really new to the Shopify API, and I'm working with someone else's code. I'm uploading a product trough my Shopify store, but I want to set some sort of policy where a product can't be sold when it's out of stock, is there a way this can be done on code?
Every time I create a product on Shopify, I do it like this:
static async createProductInShopify(product) {
const createProductsURL = SHOPIFY_URL + '/products.json';
const latestPrice = product.prices[product.prices.length - 1];
const requestBody = {
product: {
title: product.name,
body_html: product.body,
vendor: 'My Store',
product_type: 'Sample Product',
handle: product.handle,
tags: product.categories,
images: [
{
src: product.imageURL
}
],
variants: [
{
option1: product.size ? 'Big' : 'Normal',
price: latestPrice,
requires_shipping: true,
taxable: false,
inventory_quantity: product.quantity,
inventory_management: 'shopify',
inventory_policy: 'continue'
}
]
}
};
const response = await ShopifyController.fetch(createProductsURL, requestBody, 'POST', product);
const shopifyJSON = await response.json();
product.productID = `${shopifyJSON.product.id}`;
product.productVariantID = `${shopifyJSON.product.variants[0].id}`;
product.inventoryLevelID = `${shopifyJSON.product.variants[0].inventory_item_id}`;
await product.save();
return product;
}
I assume that the inventory_policy is where that flag can be set, however, I need some confirmation to see if that is true.
yes, the inventory_policy for product variant has to be set to something.
i am sharing the screenshot for the value.

Getting Error Data should be a "String", "Array of arrays" OR "Array of objects" when trying to export data to CSV in reactJS

I want to download some data that I have from my firebase firestore DB that I have listed in a table.
I am adding the data that is coming from my firestore in order to export to CSV and have a complete viewable file in my admin dashboard
But every time I try to follow the steps to download the data and export them to CSV format I get this error: "Data should be a "String", "Array of arrays" OR "Array of objects"
here is my code:
import { CSVLink } from 'react-csv';
const [data, setData] = useState([]);
const [csvData, setcsvData] = useState([]);
const list = []
const csvList = []
useEffect(() => {
firebase.firestore().collection("Users").get().then((userSnapshot) => {
userSnapshot.forEach((doc) => {
const {powerAccount,first_name,registerDate,email,company,country,phone} = doc.data();
setID(doc.data().usersID)
list.push({
usersID:doc.id,
powerAccount:powerAccount,
first_name:first_name,
registerDate:registerDate,
email:email,
company:company,
country:country,
phone:phone,
});
const userData = {
usersID: doc.id,
powerAccount: powerAccount,
first_name: first_name,
registerDate: registerDate,
email: email,
company: company,
country: country,
phone: phone,
};
const headers = [
{ label: 'Account', key: powerAccount },
{ label: 'Name', key: first_name },
{ label: 'RegistrationDate', key: registerDate },
{ label: 'Email', key: email },
{ label: 'Company', key: company },
{ label: 'Country', key: country },
{ label: 'Phone', key: phone },
];
const csvReport = {
filename: "userReport.csv",
headers: headers,
data: userData
}
csvList.push(csvReport)
});
setData(list);
setcsvData(csvList)
});
},[]);
return (
<CSVLink {...csvData} >
Export
</CSVLink>
)
I fixed this error by adding a conditional wrapper around my CSVLink component so that it didn't try to create that component before the data was loaded.
So, for your example, something like this could do the trick:
{csvData && (
<CSVLink {...csvData} >
Export
</CSVLink>
)}

Change an object value inside a loop in JavaScript

I have an array of objects like this:
const data = [{
_id:"49847444033",
name:"yoko"
},{
_id:"49847433333",
name:"doira"
}]
I have to change each item name property to something like this :
...
{
_id:"49847433333",
name:{
en:"John"
}
}
My attempt is to loop object like following :
data.forEach((item) => {
item.name = {en:"john"}
console.log(item)
})
But this always console the original item and the name property value is not modified.
const newData = data.map(user => ({ _id: user._id, name: { en: user.name } }))
I created a library to express transformations like this very simply.
const { pipe, fork, get } = require('rubico')
const data =
[ { _id: '49847444033', name: 'yoko'}
, { _id: '49847433333', name: 'doira'}
]
const onData = pipe([
fork({
_id: get('_id'), // data => data._id
name: fork({ en: get('name') }), // data => ({ en: data.name })
}),
console.log,
])
data.map(onData) /*
{ _id: '49847444033', name: { en: 'yoko' } }
{ _id: '49847433333', name: { en: 'doira' } }
*/
I've commented the code above, but to really understand rubico and get started using it, I recommend you read the intuition and then the docs
try somthing like:
const newList = data.map(obj => {
return { _id: obj._id, name: { en: obj.name } }
});
and the newList list is your new data list so you can do it:
data = newList;
EDIT:
if you have more properties you can change the return line to:
return { ...obj, name: { en: obj.name } }
what will happen here, it will deploy all the object properties as they are, and modify the name property, unfortunately, every property you want to modify, you have to re-write it.

prisma2: how to fetch nested fields?

In prisma 1 I have used fragment to fetch the nested fields.
For example:
const mutations = {
async createPost(_, args, ctx) {
const user = await loginChecker(ctx);
const post = await prisma.post
.create({
data: {
author: {
connect: {
id: user.id,
},
},
title: args.title,
body: args.body,
published: args.published,
},
})
.$fragment(fragment);
return post;
},
};
but seems like in prisma2 it is not supported. because by running this on playground,
mutation CREATEPOST {
createPost(
title: "How to sleep?"
body: "Eat, sleep, repaet"
published: true
) {
title
body
published
author {
id
}
}
}
I am getting,
"prisma.post.create(...).$fragment is not a function",
The include option is used to eagerly load relations in Prisma.
Example from docs:
const result = await prisma.user.findOne({
where: { id: 1 },
include: { posts: true },
})
Assuming a user table with a one-to-many posts relation, this will return back the user object with the posts field as well.
Prisma also supports nesting as well, for example:
const result = await prisma.user.findOne({
where: { id: 1 },
include: {
posts: {
include: {
author: true,
}
},
},
})

How to update existing object with additional data

The project is created with nodejs and mongoose. What I am trying to do is to update the existing model with addition data (which is a comment, in that case).
This is the model and its methods:
const bugSchema = new Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
date: {
type: String,
required: true
},
time: {
type: String,
required: true
},
assignedTo: {
type: String,
required: true
},
assignedBy: {
type: String,
required: true
},
status: {
type: String,
required: true
},
priority: {
type: String,
required: true
},
comments: {
comment:[
{
user:{
type: String,
required: true
},
content: {
type: String,
required: true
}
}
]
}
});
bugSchema.methods.addComment = function(comment){
const username = comment.user;
const content = comment.content;
console.log(comment);
const updatedComments = [...this.comments];
updatedComments.push({
user : username,
content: content
});
this.comments = updatedComments;
return this.save();
};
The controller, which is passing the information from the form:
exports.postComment = (req,res,next) =>{
const bugId = req.body.bugID;
const name = req.session.user.fullName;
const content = req.body.content;
const prod = {name, content};
Bug.findById(bugId).then(bug =>{
return bug.addComment(prod);
})
.then(result =>{
console.log(result);
});
};
I am getting a following error:
(node:3508) UnhandledPromiseRejectionWarning: TypeError: this.comments is not iterable
(node:3508) UnhandledPromiseRejectionWarning: TypeError: this.comments is not iterable
The error indicate you're trying to iterable a type of data which does NOT has that capability.
You can check that printing the type:
console.log(typeof this.comments)
Or even, priting the whole object:
console.log(this.comments)
as you can see, in both cases you're getting an object, not a list (how you spect)
So you can do 2 things:
1- Iterable a list
this.comments is an object but into that object you have the list you want, so just use the list instead.
bugSchema.methods.addComment = function(comment){
const username = comment.user;
const content = comment.content;
console.log(comment);
//const updatedComments = [...this.comments];
const updatedComments = [...this.comments.comment];
updatedComments.push({
user : username,
content: content
});
this.comments = updatedComments;
return this.save();
};
Or you can modify your schema making the comments a list instead of an object
2- comments as list in schema
Define the comments attribute as a list
const bugSchema = new Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
...
...,
comments:[
{
user:{
type: String,
required: true
},
content: {
type: String,
required: true
}
}
]
});
And then, try to iterable it as how you been doing
bugSchema.methods.addComment = function(comment){
const username = comment.user;
const content = comment.content;
console.log(comment);
const updatedComments = [...this.comments];
updatedComments.push({
user : username,
content: content
});
this.comments = updatedComments;
return this.save();
};
I am not sure but comments is an object and not an array so you can't push using [...this.comments] and I think it is the comment you want to push?
const updatedComments = [...this.comment];
updatedComments.push({
user : username,
content: content
});
this.comment = updatedComments;
From your schema comments is not an array. you are trying to spread an object into an array. const updatedComments = [...this.comments]; also push works on array.
try to modify your schema definitions by declaring the commentSchema outside the bugSchema.
const commentSchema = new Schema({
user:{
type: String,
required: true
},
content: {
type: String,
required: true
}
})
const bugSchema = new Schema({
comments: {
type: [commentSchema]
}
})
Bug.findByIdAndUpdate(bugId, {$push: {comments: newComment}})
Don't use findByIdAndUpdate Mongoose method, you better use save
it is written here https://mongoosejs.com/docs/tutorials/findoneandupdate.html
The findOneAndUpdate() function in Mongoose has a wide variety of use cases. You should use save() to update documents where possible, but there are some cases where you need to use findOneAndUpdate(). In this tutorial, you'll see how to use findOneAndUpdate(), and learn when you need to use it.
Below a router example
router.put('/items', (req, res) => {
if (!req.body._id || !req.body.title) {
return res.status(501).send({ message: 'Missing parameters, or incorrect parameters' });
}
return itemModel.findOne({ _id: req.body._id }, (err, item) => {
if (err) {
return res.status(500).send({
message: err
});
}
item.title = req.body.title; // <------------- You rewrite what was before stored on title attribute
return item.save((err, item) => { // <------------- You save it, this is not gonna create a new one, except if it doesn't exist already
if (err) {
return res.status(400).send({
message: 'Failed to update item'
});
} else {
return res.status(200).send({
message: 'Item update succesfully',
data: item
});
}
});
});
});

Categories

Resources