I am using knexjs and node and running postgres db with this tables: menu and menuItem having one-to-many relationship. I found a solution here knex: what is the appropriate way to create an array from results? however this returns an array of strings. What i need is to return an array of objects and an empty array if null that looks exactly as the example below:
[
{
id: 123,
name: 'Sunday Menu',
items: []
},
{
id: 456,
name: 'Monday Menu',
items: [
{
id: 987,
name: 'Fried Chicken',
pcs: 69
},
{
id: 876,
name: 'Egg Soup',
pcs: 50
},
]
}
]
My menu and menuItem table schema looks similar to this:
menu_table: {
id,
name,
timestamps
}
menuItem_table: {
id,
menu_id,
name,
pcs,
timestamps
}
Currently, my code is like this:
knex('menu').leftJoin('menuitem', 'menu.id', 'menuitem.menu_id')
.select(['menu.id as menuID', knex.raw('ARRAY_AGG(menuitem.name) as items')])
.groupBy('menu.id')
And here's the result:
[
{
"menuID": "20091fff-ca8b-42d6-9a57-9f6e1922d0fa",
"items": [
null
]
},
{
"menuID": "2ddad4fa-7293-46c5-878f-cb2881be3107",
"items": [
"Fried Chicken",
"Egg Soup",
"Vegetable Dish"
]
}
]
UPDATE: I found out how to do it using raw query how ever i can't translate it using knex. Here's my code:
SELECT menu.*, COALESCE(menuitem.items, '[]') AS items FROM menu LEFT JOIN LATERAL (
SELECT json_agg(menuitem.*) AS items FROM menuitem WHERE menu.id = menuitem.menu_id
) menuitem ON true