I'm attempting to manipulate this data in react with graphql. As you can see, I have this data or input in the graphql playground, and this is how I wanted the input to look:
In my frontend, I have a cartItem with an objects inside and array, including the product name, id, and so on. I wanted the input to look like the example I provided above. Is there a way to make that happen?
Codes and Data
This is how my cart's Item Data looks.
CartItem Data:
[
{
id: "6109401fd86d352a70e3694e",
name: "asasasasa",
sku: "sasa",
shippingTime: "1628812800000",
quantity: 1,
},
{
id: "61051c14f25d8830a8e238c0",
name: "Pringles Sour Cream & Onion Potato Crisps 158g",
sku: "sad89f79dsafs",
shippingTime: "1627084800000",
quantity: 1,
},
];
As stated in the preceding example, all I wanted was the product's id and quantity.
Order.js
const [cartItems, setCartItems] = useContext(CartContext);
const [createOrder, { data, loading }] = useMutation(CREATE_ORDER_MUTATION);
const qty = cartItems.map(({ quantity }) => {
return quantity;
});
const cartItemId = cartItems.map(({ id }) => {
return id;
});
function onSubmit() {
createOrder({
variables: {
qty: qty,
products: cartItemId,
paymentMethod: paymentMethod,
address: address,
},
})
}
Whenever I need to console someone. If you log the cartItemId, you'll get something like this:
Same goes with my qty.
Please let me know if you have any other questions or require any additional code, and I will gladly offer it.
Apollo Mutation:
const CREATE_ORDER_MUTATION = gql`
mutation createOrder(
$qty: Int!
$products: String!
$paymentMethod: String!
$address: String!
) {
createOrder(
orderedItems: [{ qty: $qty, products: $products }]
paymentMethod: $paymentMethod
address: $address
) {
id
orderedItems {
qty
products {
id
name
sku
description
}
}
}
}
`;
The code below will transform the cartItems into the desired result. You can loop through the cartItems and create an object with the required structure for each item.
const orderedItems = cartItems.map(({ id, quantity }) => {
return {
qty: quantity,
products: id,
};
});
Complete code will look something like this
const [cartItems, setCartItems] = useContext(CartContext);
const [createOrder, { data, loading }] = useMutation(CREATE_ORDER_MUTATION);
// Restructure the array to desired format
const orderedItems = cartItems.map(({ id, quantity }) => {
return {
qty: quantity,
products: id,
};
});
console.log(orderedItems); // To check if it looks correct
function onSubmit() {
createOrder({
variables: {
orderedItems: orderedItem,
paymentMethod: paymentMethod,
address: address,
},
})
}
Related
my state orderDetail contain orderDetail json
I am getting the _id of the order which I want to delete in function eg _id: 60f1ab20891ced4818b5ea87,
now I want to remove this order from the orders array which is in orderdetail and update the state.
orderdetail = {
_id: 60f1ab20891ced4818b5ea86,
totalPrice: '400',
orders: [
{
_id: 60f1ab20891ced4818b5ea87,
quantity: '1',
price: 200,
name: 'Caramel Latte',
category: 'Steaming Cups'
},
{
_id: 60f1ab20891ced4818b5ea88,
quantity: '1',
price: 200,
name: 'Cinnamon Latte',
category: 'Steaming Cups'
}
],
confirm: 'done',
timestamp: 1626450720332,
name: 'xxx',
email: 'xxx',
}
what I did is clone state then uses for loop to find an index of the order then remove that index element in clone then update state to clone. any other less computation method?
What you need to so is set a new object with the orders array filtered as well as a new totalPrice.
For example
const [orderDetail, setOrderDetail] = useState( /* whatever */ )
const deleteOrder = (id) => {
setOrderDetail(prev => {
// filter out the order by ID
const orders = prev.orders.filter(({ _id }) => _id !== id)
return {
...prev,
orders, // overwrite orders
totalPrice: orders.reduce((total, { quantity, price }) =>
total + quantity * price, 0), // calculate new total
timestamp: Date.now() // perhaps you want to update this too
}
})
}
This uses the functional update version of the useState() hook to easily get access to the previous state value.
As my "finalArr" has many items, how can I post every item using map. Below code works fine if I have only one item. But I'm facing problem when "finalArr" have more items in it.
const orders = [{
name: finalArr[0][0].name,
productImage: finalArr[0][0].productImage,
price: finalArr[0][0].price,
quantity: finalArr[0][1],
}, ];
const customerData = {
username,
orders,
};
axios
.post("http://localhost:5000/api/cart", customerData)
.then((res) => {
console.log(res.data);
})
Use Array.prototype.map. Try below:
const orders = finalArr.map(e => ({
name: e[0].name,
productImage: e[0].productImage,
price: e[0].price,
quantity: e[1],
}));
I'm trying to build a simple budgeting app.
Whenever I insert this model into my app. I get a proxy for the expenses. Where is the flaw in my thinking?
I have an action on the Budget.js
when I print it in the useEffect this is what console.log outputs for the expenses a proxy.
I'm expecting it to print the actual data from the initial state.
React.useEffect(() => {
budget.addDummyData()
console.log(budget.expenses)
}, [])
[[Handler]]: Object
[[Target]]: Array(0)
[[IsRevoked]]: false
//////////////////////////////////////////////////////////////////////
//SubCategory
const SubCategory = types
.model('SubCategory', {
id: types.maybeNull(types.string, ''),
name: types.maybeNull(types.string, ''),
amount: types.maybeNull(types.number, 0)
})
const SubCategoryStore = types.model({ subCategory: types.optional(SubCategory, {}) })
export default SubCategoryStore
/////////////////////////////////////////////////////////////////////////
//Category.js
const Category = types
.model('Category', {
id: types.maybeNull(types.string, ''),
name: types.maybeNull(types.string, ''),
subCategories: types.array(SubCategory)
})
const CategoryStore = types.model({ category: types.optional(Category, {}) })
export default CategoryStore
///////////////////////////////////////////////////////////////
// Budget
const Budget = types
.model('Budget', {
totalIncome: 200,
expenses: types.array(Category)
// incomes: types.optional(types.array(Category), [])
}).actions({
addDummyData() {
self.expenses.push(initialStateExpenses)
}
})
const BudgetStore = types.model({ budget: types.optional(Budget, {}) })
export default BudgetStore
const initialStateExpenses = {
id: '123',
name: 'Food',
subCategories: [
{
id: '1314',
name: 'Grocery',
amount: 250
},
{
id: '1442',
name: 'Restaurants',
amount: 50
}
]
}
expenses is of type Category[], you are passing an object. I assume you want to set the expenses from subCategories. If so you can try this
addDummyData() {
initialStateExpenses.subCategories.forEach(ex => self.expenses.push(ex))
}
or
addDummyData() {
self.expenses = initialStateExpenses.subCategories
}
A better approach would be to pass the initialStateExpenses via args to the addDummyData function so your model doesn't depend on external variables
addDummyData(initialStateExpenses) {
initialStateExpenses.subCategories.forEach(ex => self.expenses.push(ex))
}
or
addDummyData(initialStateExpenses) {
self.expenses = initialStateExpenses.subCategories
}
then use it like
budget.addDummyData(initialStateExpenses)
I am attempting to insert a cart of items as a JSON object into a MongoDB collection using a mongoose schema.
The customer's ID is getting stored (which comes from the User DB), but the cart items are not. Here is my code:
Sample order data contained in local variable app.js called cartData: { data:[] }:
{
data: [
item {
name: "Product Name 1",
price: '2.99',
sku: '13579',
count: 8
},
item {
name: 'Product Name 2',
price: '21.99',
sku: '24680',
count: 2
}
]
}
Cart.js (Cart Schema):
const mongoose = require("mongoose")
const CartSchema = new mongoose.Schema({
customerID: {
type: String,
required: true
},
cartContents: {
type: [Object]
},
date: {
type: Date,
default: Date.now
}
}, { collection: "ordersDB" })
const Cart = mongoose.model('Cart', CartSchema)
module.exports = Cart
app.js (Order Submit Code):
const Cart = require("../models/Cart")
const customerID = req.user.customerID //Acquired from user database
const newOrder = new Cart({
customerID,
cartData
})
newOrder.save()
.then(customer => {
req.flash("successful", "Your order has been submitted!")
res.redirect("/somepage")
})
.catch(err => console.log(err))
Result:
_id: abcd1234
> cart: Object
> type: Array
> <The Infinite Abyss Of Nothingness aka Empty>
customerID: "1234567890"
date: 2019-12-11T21:14:40.825+00:00
__v: 0
Any insight on this problem would be greatly appreciated.
Based on provided schema Mongoose expects you to pass a field called cartContents. Any other field not compatible with your schema will be ignored. To fix that just name your field explicitly:
const newOrder = new Cart({
customerID,
cartContents: cartData
})
I'm stuck with the code. I actually want to filter elements in dataLayer using typescript/javascript.
I have dataLayer defined as shown below
track: { products },
dataLayers: { current: { cart: { items } } }
products?: IProduct[]
export interface IProduct {
id: string
quantity?: string
name?: string
}
items?: ICartItem[]
export interface ICartItem {
id: string
brand: string
name: string
quantity: number
}
track: { products }
products have {id,quantity}
dataLayers: { current: { cart: { items } } }
items have {id, brand, name, quantity }
Now I want to filter id and get the name of the product, For Example:
Example:
*
products:{
[{id: 'a123',quantity: '1'},{id:'a345', quantity:'2'}]
}
items:{
[{id: 'a123',brand:'pen',name: 'Reynolds', quantity: '1'}, {id: 'a143',brand:'pencil',name: 'Nataraj', quantity: '3'}, {id: 'a122',brand:'pen',name: 'Parker',quantity: '1'},{id:'a345',brand:'Eraser',name: 'Faber-Castell', quantity:'2'}]
}*
Expected output
id:a123,name:'Reynolds'
id:a345,name:'Faber-Castell'
my code:
const id = products.map(product => { return product.id})
items.filter((item) => {
return item.id === id
})
.map((item)=> {
const { id, name } = item
console.log("id" + id)
console.log("name" + name)
})
Actual output
Giving error
**
const id: string[]
This condition will always return 'false' since the types 'string' and 'string[]' have no overlap.ts(2367)
**
Why am I not able to compare item.id with id
You are comparing the string array id with each item id which is a string. Do like below.
items.filter(item => id.includes(item.id))
In the first line of your code, you are fetching the array of ids from products array. Hence id is nothing but an array.
const id: string[] = products.map(product => { return product.id })
Therefore, the below code will do the job.
items.filter((item) => id.includes(item.id) )
Also, If you are coding in typescript, develop the habit of using variable with its types. [number, string, boolean, string[] ...]