'What is the best way to split data based on product owners in reactjs or nodejs
I need some idea!
Is there any possible way To separate user orders based on vendor email? I am trying to develop a multi-vendor project where vendors can be able to upload products. I am trying to do when a user orders from a different shop the orders need to be split based on vendor email.
Suppose a customer trying to buy from x vendor and y vendor products. When customers order the products the data look like the below array objects. It is difficult to show vendor orders in their dashboard who ordered your product. So I am trying to split the order based on email also the amount will be divided between the vendors from paymentDetail.amount when splitting the order.
[
{
_id: "622d70a49bd88b1599026318",
products: [
{
_id: "6223186e2278d4e502f5264a",
title: "Product number 1",
price: 600,
cartQuantity: 1,
vendor: {email: "[email protected]"}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "[email protected]"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "[email protected]"
}
},
],
paymentDetails: {
createdId: 1647145079,
date: "Sun Mar 13 2022",
amount: 700,
email: "[email protected]",
last4: "4242",
transaction: "p"
},
status: "Pending",
billing: {
country: "BD",
name: "Md. Fathe Karim",
phone: "+88010000000",
line1: "Madhabdi",
city: "Narshingdi",
postal_code: "1604",
state: "Bandarban"
}
}]
This is my POST request from frontend:
await fetch('https://guarded-ocean-73313.herokuapp.com/dashboard/orders', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
products: [...cart], paymentDetails: {
createdId: paymentIntent.created,
date,
amount: paymentIntent.amount,
email: emailRef.current?.value,
billing: paymentIntent.billing_details,
last4: paymentMethod.card.last4,
transaction: paymentIntent?.client_secret.slice('_secret')[0]
},
status: 'Pending',
billing: {
country: countryRef.current?.value,
name: nameRef.current?.value,
phone: phoneRef.current?.value,
line1: addressRef.current?.value,
city: cityRef.current?.value,
postal_code: zipRef.current?.value,
state: stateRef.current?.value,
}
})
})
.then(res => res.json())
This is my order API
app.post('/dashboard/orders', async (req, res) => {
const productDetail = req.body
const result = await unityMartOrdersCollection.insertOne(productDetail)
res.json(result)
})
My expectation is something like this:
[
{
_id: "622d70a49bd88b1599026318", // Vendor 1 Order
products: [
{
_id: "6223186e2278d4e502f5264a",
title: "Product number 1",
price: 600,
cartQuantity: 1,
vendor: {email: "[email protected]"}
}
],
paymentDetails: {
createdId: 1647145079,
date: "Sun Mar 13 2022",
amount: 600, // price redcuded because we divided the product
email: "[email protected]",
last4: "4242",
transaction: "p"
},
status: "Pending",
billing: {
country: "BD",
name: "Md. Fathe Karim",
phone: "+88010000000",
line1: "Madhabdi",
city: "Narshingdi",
postal_code: "1604",
state: "Bandarban"
}
},
{
_id: "622d70a49bd88b1599026319", // Vendor 2 Order
products: [
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "[email protected]"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "[email protected]"
}
},
],
paymentDetails: {
createdId: 1647145079,
date: "Sun Mar 13 2022",
amount: 200, // price redcuded because we divided the product
email: "[email protected]",
last4: "4242",
transaction: "p"
},
status: "Pending",
billing: {
country: "BD",
name: "Md. Fathe Karim",
phone: "+88010000000",
line1: "Madhabdi",
city: "Narshingdi",
postal_code: "1604",
state: "Bandarban"
}
}
]
I think it's possible by the reduce method?
can someone give me any idea how can I be able to display the vendor's order into their dashboard? If my thinking is wrong you can share your idea.
Solution 1:[1]
This may be one possible solution to achieve the desired objective:
Code Snippet
const groupByVendor = arr => (
arr.map(order => (
Object.values( // sub-objective 1 - get values from object
order.products.reduce(
(fin, p) => ({
...fin,
...(
[p.vendor.email] in fin
? {
[p.vendor.email]: {
...fin[p.vendor.email],
products: fin[p.vendor.email].products.concat([{...p}]),
paymentDetails: {
...structuredClone(fin[p.vendor.email].paymentDetails),
amount: fin[p.vendor.email].paymentDetails.amount + p.price
} // sub-objective 2 - add price to existing amount
}
}
: {
[p.vendor.email]: {
...structuredClone(order), // sub-objective 3 - add order info here
paymentDetails: {
...structuredClone(order.paymentDetails),
amount: p.price // sub-objective 2 - set amount to price
},
products: [{...p}]
}
}
)
}),
{}
)
)
)).flat()
);
const rawData = [{
_id: "622d70a49bd88b1599026318",
products: [{
_id: "6223186e2278d4e502f5264a",
title: "Product number 1",
price: 600,
cartQuantity: 1,
vendor: {
email: "[email protected]"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "[email protected]"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "[email protected]"
}
},
],
paymentDetails: {
createdId: 1647145079,
date: "Sun Mar 13 2022",
amount: 700,
email: "[email protected]",
last4: "4242",
transaction: "p"
},
status: "Pending",
billing: {
country: "BD",
name: "Md. Fathe Karim",
phone: "+88010000000",
line1: "Madhabdi",
city: "Narshingdi",
postal_code: "1604",
state: "Bandarban"
}
}];
console.log(groupByVendor(rawData));
Explanation
The idea is to break down the desired objective into simpler, more-manageable sub-objectives.
Sub-objective 1: A dictionary mapping vendors with orders
- First, generate an object with props as the
vendoremail. - The values will be the actual order corresponding to the vendor
- Once this object is created, all we need is the values array
Sub-objective 2: A mechanism to update the paymentDetailss amount
- If processing a vendor that is not already present, set
amounttoprice - If vendor already present, add
priceto existingamount
Sub-objective 3: Transform the structure of the object
- The target requires each object in the array have
paymentDetails,billingetc. - So, when generating the values for the vendor-object/dictionary/map, account for the corresponding transformations
The sub-objectives are marked in the code-snippet for reference.
Please use comments to ask any questions, clarifications, or suggest improvements.
NOTE
- This answer employs structuredClone in order to perform deep-cloning of the
orderobject. - My reference was Jeremy's this answer as well as this one
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jsN00b |
