node.jsexpressmysql2

How to get a mysql inner join data (one to many relation) from node js nested array of objects


I am tried to get an array from mysql2 in node js but I am only getting two separate arrays from mysql2 How can I resolve the issue

export const getOrderProducts = async (req, res) => {
  const { user_id, order_id } = req.params;

  const opt = {
    sql: `select orders.id , orders.order_status ,products.id as product_id, products.name,products.quantity  from users INNER JOIN orders on orders.user_id=users.unique_id INNER JOIN delivery_details on delivery_details.order_id = orders.id INNER JOIN delivery_types on delivery_types.id=orders.delivery_type_id INNER JOIN order_products on order_products.order_id = orders.id INNER JOIN products on products.id = order_products.product_id where users.unique_id='${user_id}' and orders.id='${order_id}'`,
    nestTables: true,
  };

  try {
    const data = await query(opt);
    return res.json(Success("Orders", data));
  } catch (error) {
    return res.status(500).json(Error("Internal Server Error try again", error));
  }
};

Output :

 [
        {
            "orders": {
                "id": 12,
                "order_status": "PENDING"
            },
            "products": {
                "product_id": 4,
                "name": "Sugarcane Juice",
                "quantity": "1"
            }
        },
        {
            "orders": {
                "id": 12,
                "order_status": "PENDING"
            },
            "products": {
                "product_id": 5,
                "name": "Milo ice",
                "quantity": "1"
            }
        }
    ]

Expected Output : 

 [
        {            
            "id": 12,
            "order_status": "PENDING",
            "products": [{
                "product_id": 4,
                "name": "Sugarcane Juice",
                "quantity": "1"
            },{
                "product_id": 5,
                "name": "Milo ice",
                "quantity": "1"
            }]     
        }
 ]

I am using the mysql2 package and options sql and nestTables as you see below code how can I get the expected output of my code and i achieved only MySQL code without any JS functions Thanks in Advance


Solution

  • You could do something like this. Combine the data in the form you want to have e.g. using the (...)-spread operator.

    And in case you have multiple orders, you can check for using findIndex().
    Depending on that you can create a new orders entry or insert a product into a existing order.

    
    
    export const getOrderProducts = async (req, res) => {
      const { user_id, order_id } = req.params;
    
      const opt = {
        sql: `select orders.id , orders.order_status ,products.id as product_id, products.name,products.quantity  from users INNER JOIN orders on orders.user_id=users.unique_id INNER JOIN delivery_details on delivery_details.order_id = orders.id INNER JOIN delivery_types on delivery_types.id=orders.delivery_type_id INNER JOIN order_products on order_products.order_id = orders.id INNER JOIN products on products.id = order_products.product_id where users.unique_id='${user_id}' and orders.id='${order_id}'`,
        nestTables: true,
      };
    
      try {
        const data = await query(opt);
    
        const responseBody = [];
        for (const row of data) {
          const { products, orders } = row;
          const indexOf = responseBody.findIndex(item => item.orders_id === orders.orders_id);
    
          if (indexOf === -1) {
            responseBody.push({
              ...orders,
              products: [products],
            });
          } else {
            responseBody[indexOf].products.push(products);
          }
        }
    
    
        return res.json(Success("Orders", responseBody));
      } catch (error) {
        return res.status(500).json(Error("Internal Server Error try again", error));
      }
    };
    

    Result:

    [
      {
        "id": 12,
        "order_status": "PENDING",
        "products": [
          {
            "product_id": 4,
            "name": "Sugarcane Juice",
            "quantity": "1"
          },
          {
            "product_id": 5,
            "name": "Milo ice",
            "quantity": "1"
          }
        ]
      }
    ]