I have an association many to many with two tables, products and orders. In my pivot table i save the id, quantity and price of the product. When I fetch the product i need the name of this product, but to get the name I need to get in the product table. The response of my fetching return like this
{
"id": 111,
"name": "Matheus",
"phonenumber": "69993750103",
"reference": null,
"value_subtotal": "10.000",
"value_delivery": "5.000",
"value_total": "15.000",
"status": "pending",
"products": [
{
"name": "Açai 350ml",
"OrdersProducts": {
"quantity": 2,
"price": "0.000"
}
},
{
"name": "acai 350ml",
"OrdersProducts": {
"quantity": 3,
"price": "0.000"
}
}
]
}
but i need the json in this format
{
"id": 111,
"name": "Matheus",
"street": "Rua olavo bilac",
"phonenumber": "69993750103",
"number": "3511",
"reference": null,
"note": "Retirar o morango",
"value_subtotal": "10.000",
"value_delivery": "5.000",
"value_total": "15.000",
"status": "pending",
"createdAt": "2021-10-20T18:26:25.000Z",
"updatedAt": "2021-10-20T18:26:25.000Z",
"products": [
{
"name": "Açai 350ml",
// here the difference, i want create a single object in the return, with all data i need of the product
"quantity": 2,
"price": "0.000"
}
},
{
"name": "acai 350ml",
"quantity": 3,
"price": "0.000"
}
]
}
My controller
async getOrder(req, res) {
const { id } = req.params;
const order = await Orders.findByPk(id, {include: [{
association: 'products',
attributes: ['name'],
through: {
attributes:['quantity', 'price'],
},
raw: true,
}]})
if (!order) return res.status(404).send({ message: 'order ${`id`}' })
return res.json(order);
},
Maybe you can implement the query without the association but using model.
async getOrder(req, res) {
const { id } = req.params;
const order = await Orders.findByPk(id, {include: [{
model: Product,
attributes: ['name'],
include: [{
association: "OrdersProducts",
attributes:['quantity', 'price'],
raw: true,
}],
}]})
if (!order) return res.status(404).send({ message: 'order ${`id`}' })
return res.json(order);
},
You will still get order.quantity and order.price as a name at product as properties.
var a = {
"id": 111,
"name": "Matheus",
"phonenumber": "69993750103",
"reference": null,
"value_subtotal": "10.000",
"value_delivery": "5.000",
"value_total": "15.000",
"status": "pending",
"products": [{
"name": "Açai 350ml",
"OrdersProducts": {
"quantity": 2,
"price": "0.000"
}
},
{
"name": "acai 350ml",
"OrdersProducts": {
"quantity": 3,
"price": "0.000"
}
}
]
};
var orders = [];
orders.push(a);
var updatedOrders = orders.map(function(order) {
order.products.forEach(function(product) {
product.price = product.OrdersProducts.price;
product.quantity = product.OrdersProducts.quantity;
delete product.OrdersProducts;
});
return order;
});
console.log(updatedOrders);
If you have control over the order and/or product object, you can add custom toJSON method. You can format the json output away you want. https://futurestud.io/tutorials/create-a-custom-tojson-function-in-node-js-and-javascript
If you do not have control of the object, a function could be made to format the order.
const order = {
"id": 111,
"name": "Matheus",
"phonenumber": "69993750103",
"reference": null,
"value_subtotal": "10.000",
"value_delivery": "5.000",
"value_total": "15.000",
"status": "pending",
"products": [
{
"name": "Açai 350ml",
"OrdersProducts": {
"quantity": 2,
"price": "0.000"
}
},
{
"name": "acai 350ml",
"OrdersProducts": {
"quantity": 3,
"price": "0.000"
}
}
]
};
order.products = order.products.map(({OrdersProducts, ...other}) => ({...other, ...OrdersProducts}));
I prefer custom toJSON methods. This, of course, depends on the access to the object structure.