ng-repeat HTML table with colspan and rowspan from nested json - html

I'm trying to achieve table structure attached in the image :
Composite Class Routine
So far what I've tried can be seen in the following Plunker:
https://plnkr.co/edit/4WiWKDIM2bNfnmRjFo91?p=preview
My json data is :
$scope.routines = [
{
"WEEKDAY_ID": 1,
"WEEKDAY": "Sunday",
"aSemester": [
{
"SEMESTER_ID": 1,
"SEMESTER_NAME": "1st",
"aClassTime": [
{
"COURSE_ID": 1,
"COURSE_CODE": "CSTE-1001",
"CLASS_DURATION": 3,
"CLASSTIME_ID": 1,
"CLASSTIME": "9.00-9.50",
"DEPT_ID": 1,
"DEPT_NAME": "Computer Science",
"BUILDING_NAME": "Academic-1",
"ROOM_NO": 101,
"LAB_GROUP": null,
"INSTRUCTOR_ID": 10,
"INSTRUCTOR_NAME": "Abhijit Chakraborty",
"SHORT_CODE": "AC"
},
{
"COURSE_ID": 7,
"COURSE_CODE": "CSTE-1106",
"CLASS_DURATION": 1,
"CLASSTIME_ID": 4,
"CLASSTIME": "12.00-12.50",
"DEPT_ID": 1,
"DEPT_NAME": "Computer Science",
"BUILDING_NAME": "Academic-2",
"ROOM_NO": 258,
"LAB_GROUP": null,
"INSTRUCTOR_ID": 10,
"INSTRUCTOR_NAME": "Abhijit Chakraborty",
"SHORT_CODE": "AC"
},
{
"COURSE_ID": 3,
"COURSE_CODE": "CSTE-1102",
"CLASS_DURATION": 1,
"CLASSTIME_ID": 7,
"CLASSTIME": "4.00-4.50",
"DEPT_ID": 1,
"DEPT_NAME": "Computer Science",
"BUILDING_NAME": "Academic-2",
"ROOM_NO": 252,
"LAB_GROUP": null,
"INSTRUCTOR_ID": 9,
"INSTRUCTOR_NAME": "Dr. Md. Asadun Nabi",
"SHORT_CODE": "MAN"
}
]
},
{
"SEMESTER_ID": 2,
"SEMESTER_NAME": "2nd",
"aClassTime": [
{
"COURSE_ID": 7,
"COURSE_CODE": "CSTE-1106",
"CLASS_DURATION": 1,
"CLASSTIME_ID": 1,
"CLASSTIME": "9.00-9.50",
"DEPT_ID": 1,
"DEPT_NAME": "Computer Science",
"BUILDING_NAME": "Academic-4",
"ROOM_NO": 456,
"LAB_GROUP": null,
"INSTRUCTOR_ID": 6,
"INSTRUCTOR_NAME": "Dr. Humayun Kabir",
"SHORT_CODE": "HK"
},
{
"COURSE_ID": 3,
"COURSE_CODE": "CSTE-1102",
"CLASS_DURATION": 1,
"CLASSTIME_ID": 2,
"CLASSTIME": "10.00-10.50",
"DEPT_ID": 1,
"DEPT_NAME": "Computer Science",
"BUILDING_NAME": "Academic-1",
"ROOM_NO": 102,
"LAB_GROUP": null,
"INSTRUCTOR_ID": 6,
"INSTRUCTOR_NAME": "Dr. Humayun Kabir",
"SHORT_CODE": "HK"
}
]
},
{
"SEMESTER_ID": 3,
"SEMESTER_NAME": "3rd",
"aClassTime": [
{
"COURSE_ID": 5,
"COURSE_CODE": "CSTE-4202",
"CLASS_DURATION": 1,
"CLASSTIME_ID": 7,
"CLASSTIME": "4.00-4.50",
"DEPT_ID": 1,
"DEPT_NAME": "Computer Science",
"BUILDING_NAME": "Academic-2",
"ROOM_NO": 252,
"LAB_GROUP": null,
"INSTRUCTOR_ID": 7,
"INSTRUCTOR_NAME": "Md. Javed Hossain",
"SHORT_CODE": "MJH"
}
]
},
{
"SEMESTER_ID": 4,
"SEMESTER_NAME": "4th",
"aClassTime": [
{
"COURSE_ID": 61,
"COURSE_CODE": "CSTE-2204",
"CLASS_DURATION": 2,
"CLASSTIME_ID": 1,
"CLASSTIME": "9.00-9.50",
"DEPT_ID": 1,
"DEPT_NAME": "Computer Science",
"BUILDING_NAME": "Academic-1",
"ROOM_NO": 404,
"LAB_GROUP": null,
"INSTRUCTOR_ID": 6,
"INSTRUCTOR_NAME": "Dr. Humayun Kabir",
"SHORT_CODE": "HK"
},
{
"COURSE_ID": 62,
"COURSE_CODE": "CSTE-2206",
"CLASS_DURATION": 2,
"CLASSTIME_ID": 3,
"CLASSTIME": "11.00-11.50",
"DEPT_ID": 1,
"DEPT_NAME": "Computer Science",
"BUILDING_NAME": "Academic-1",
"ROOM_NO": 101,
"LAB_GROUP": null,
"INSTRUCTOR_ID": 10,
"INSTRUCTOR_NAME": "Abhijit Chakraborty",
"SHORT_CODE": "AC"
},
{
"COURSE_ID": 63,
"COURSE_CODE": "CSTE-2202",
"CLASS_DURATION": 3,
"CLASSTIME_ID": 5,
"CLASSTIME": "2.00-2.50",
"DEPT_ID": 1,
"DEPT_NAME": "Computer Science",
"BUILDING_NAME": "Academic-3",
"ROOM_NO": 303,
"LAB_GROUP": null,
"INSTRUCTOR_ID": 7,
"INSTRUCTOR_NAME": "Md. Javed Hossain",
"SHORT_CODE": "MJH"
}
]
}
]
}
];
and html I tried so far is :
<table id="routines" class="table table-bordered table-responsive table-condensed">
<thead>
<tr>
<th>Day</th>
<th>Semester</th>
<th ng-repeat="c in classtimes">{{c.CLASSTIME}}</th>
</tr>
</thead>
<tbody ng-repeat="r in routines">
<tr ng-repeat="s in r.aSemester">
<td rowspan="{{r.aSemester.length}}">{{r.WEEKDAY}}</td>
<td>{{s.SEMESTER_NAME}}</td>
<td colspan={{c.CLASS_DURATION}}
ng-repeat="c in s.aClassTime">
{{c.COURSE_CODE}}
</td>
</tr>
</tbody>
any kind of help would be appreciated.

Replace your table body with this
<tbody>
<tr ng-repeat-start="r in routines">
<td rowspan="{{r.aSemester.length+1}}">{{r.WEEKDAY}}</td>
</tr>
<tr ng-repeat="aSem in r.aSemester">
<td>{{aSem.SEMESTER_NAME}}</td>
<td ng-repeat="c in classtimes">
<span ng-repeat="classTime in aSem.aClassTime">
<span ng-if="classTime.CLASSTIME_ID==c.CLASSTIME_ID">
{{classTime.COURSE_CODE}}
</span>
</span>
</td>
</tr>
<tr ng-repeat-end ></tr>
</tbody>
I think this should help.
Plunkr https://plnkr.co/edit/QFUouMmSKtBiAWMdGpCC?p=preview

Related

Postgresql -> JSON Array to rows

One of the columns in my table, has JSONArray data. I have used jsonb_agg() in a jsonb column to a view. Now the data from view looks like below
[
{
"Android": 2,
"Windows": 1,
"Macintosh": 1
},
{
"iOS": 1,
"Android": 2,
"Windows": 2,
"Macintosh": 2
},
{},
{
"Android": 1,
"Windows": 1
},
{
"Android": 1
},
{
"iOS": 1,
"Android": 2
},
{
"iOS": 2,
"Android": 1
},
{
"iOS": 2
},
{
"Android": 1
},
{
"iOS": 2,
"Windows": 1
},
{
"Android": 5
},
{},
{},
{
"iOS": 1,
"Android": 1
},
{},
{},
{
"Windows": 3
}
]
However, I need to product the below result
{
"Android": 16,
"Windows": 8,
"Macintosh": 3,
"iOS": 9
}
Is there a way within PostgreSQL to achieve this?
Yes there is a way. Here it is.
select to_jsonb(t.*) from
(
select
sum((j->>'Android')::numeric) "Android",
sum((j->>'Windows')::numeric) "Windows",
sum((j->>'Macintosh')::numeric) "Macintosh",
sum((j->>'iOS')::numeric) "iOS"
from jsonb_array_elements('[{"Android": 2, "Windows": 1, "Macintosh": 1}, {"iOS": 1, "Android": 2, "Windows": 2, "Macintosh": 2}, {}, {"Android": 1, "Windows": 1}, {"Android": 1}, {"iOS": 1, "Android": 2}, {"iOS": 2, "Android": 1}, {"iOS": 2}, {"Android": 1}, {"iOS": 2, "Windows": 1}, {"Android": 5}, {}, {}, {"iOS": 1, "Android": 1}, {}, {}, "Windows": 3}]'::jsonb) as j
) as t;
As a parameterized query:
select to_jsonb(t.*) from
(
select
sum((j->>'Android')::numeric) "Android",
sum((j->>'Windows')::numeric) "Windows",
sum((j->>'Macintosh')::numeric) "Macintosh",
sum((j->>'iOS')::numeric) "iOS"
from jsonb_array_elements(?::jsonb) as j
) as t;
You can use dynamic key, value like that:
with data as (
select
je.key,
sum(je.value::int)
from
json_array_elements('[{"Android": 2, "Windows": 1, "Macintosh": 1}, {"iOS": 1, "Android": 2, "Windows": 2, "Macintosh": 2}, {}, {"Android": 1, "Windows": 1}, {"Android": 1}, {"iOS": 1, "Android": 2}, {"iOS": 2, "Android": 1}, {"iOS": 2}, {"Android": 1}, {"iOS": 2, "Windows": 1}, {"Android": 5}, {}, {}, {"iOS": 1, "Android": 1}, {}, {}, {"Windows": 3}]') d
cross join json_each_text(d) as je
group by 1
)
select json_object_agg(d.key, d.sum)
from data d
Or if you have table and column you can use this sample format like that:
with data as (
select
je.key,
sum(je.value::int)
from
your_table t join
json_array_elements(t.your_json_coulmn) d on true
cross join json_each_text(d) as je
group by 1
)
select json_object_agg(d.key, d.sum)
from data d
You can combine many json/jsonb functions to get the result
SELECT
jsonb_agg(json_build_object(key, sum))
FROM (
SELECT
key,
sum(value)
FROM (
SELECT
(arr).key,
(arr).value::int
FROM (
SELECT
jsonb_each(j) arr
FROM (
SELECT
jsonb_array_elements('[{"Android": 2, "Windows": 1, "Macintosh": 1}, {"iOS": 1, "Android": 2, "Windows": 2, "Macintosh": 2}, {}, {"Android": 1, "Windows": 1}, {"Android": 1}, {"iOS": 1, "Android": 2}, {"iOS": 2, "Android": 1}, {"iOS": 2}, {"Android": 1}, {"iOS": 2, "Windows": 1}, {"Android": 5}, {}, {}, {"iOS": 1, "Android": 1}, {}, {}, {"Windows": 3}]
'::jsonb) AS j) AS jpart) AS x) sub
GROUP BY
1) AS sub2
output: [{"Windows": 8}, {"Android": 16}, {"iOS": 9}, {"Macintosh": 3}]

Retriving Values and sum them from a table coulm which is in NESTED Json Format- SQL

Hi I'm trying to retrieve values from a Nest Json Column of a table and sum them. Which look's like below,
ID Details Created_At
2345 2021-05-31
3243 2021-06-02
3243 2021-06-02
3243 2021-06-02
Here the 'Details' column is the one which has json values in it per row, in below format
{
"new_products": [
{
"bucket": "READY",
"sku": "46123445323423",
"overaged": 0,
"transfer": 0,
"total_count": 14,
"actual_count": 14,
"lock_quantity": 0
},
],
"old_products": [
{
"bucket": "READY",
"sku": "451902224524",
"overaged": 0,
"transfer": 0,
"total_count": 59,
"actual_count": 59,
"lock_quantity": 0
},
{
"bucket": "READY",
"sku": "46123445323423",
"overaged": 0,
"transfer": 0,
"total_count": 14,
"actual_count": 14,
"lock_quantity": 0
},
{
"bucket": "READY",
"sku": "42342361484",
"overaged": 0,
"transfer": 0,
"total_count": 29,
"actual_count": 29,
"lock_quantity": 0
},
{
"bucket": "READY",
"sku": "23234234342",
"overaged": 0,
"transfer": 0,
"total_count": 57,
"actual_count": 57,
"lock_quantity": 0
}
]
}
What i have been able to achieve in my query :
SELECT ID,
Created_At,
(json_extract(Details,'$.old_products') ) AS column
FROM Table)
This just extracts 'old_products' values in a new column,
But, I'm trying to sum all the values of total_count , actual_count from key 'old_products','new_products' of every row into a new column.
How can that be achieved?

Is there a way to pass a value or variable into json_path in Mysql

Is there a way to pass a value or variable into json_path in Mysql?
I am trying to use json_table to get value from the header of my json and then get date in my content from the index that i got.
In my code below, i am trying to passe the value jsh.cName
My query
Select jsh.cName, jsc.qteRecu from
DocumentField as df inner join DocumentAnchor DA on DA.currentDocId IN (
Select df.documentId from
DocumentField as df inner join DocumentAnchor DA on DA.currentDocId = df.documentId
inner join tpl_fields TF on TF.id = df.fieldId and TF.fieldId = 135 AND df.calcValue = "13476148-0" -- $135$
) inner join tpl_fields TF on TF.id = df.fieldId and TF.fieldId = 143 AND JSON_VALID(df.calcValue)
inner join Template on Template.id = DA.templateId AND Template.TypeTemplate_id = 6 -- bordereau de livraison
CROSS JOIN JSON_TABLE(
JSON_UNQUOTE(df.calcValue), "$.header[*]"
COLUMNS(
cId INT path '$."globalColumnId"',
cName VARCHAR(256) PATH '$."name"')
) as jsh ON jsh.cId = 8
CROSS JOIN JSON_TABLE(
JSON_UNQUOTE(df.calcValue), "$.content[*]"
COLUMNS(
qteRecu VARCHAR(256) PATH "$.MY_DATE_HERE(jsh.cName)")
) as jsc
WHERE jsc.qteRecu != "" AND jsc.qteRecu IS NOT NULL;
My json, there is the header where i got the name of the key and content is where i'am trying to get the value from the key name :
"header": [
{
"id": 1026,
"name": "No projet",
"templateId": 213,
"tpl_fieldId": 3374,
"pageId": 0,
"isLineDefiner": 0,
"startValue": "",
"mandatoryStartValue": 0,
"stopValue": "",
"mandatoryStopValue": 0,
"defaultValue": "",
"width": 50,
"height": 238,
"x1": 1226,
"y1": 627,
"x2": 1276,
"y2": 864,
"ocrConfTolerance": 65,
"zoneTolerencePix": null,
"mask": null,
"created": "2021-06-14 15:29:39",
"createdBy": 1,
"modified": "2021-06-14 15:29:39",
"modifiedBy": null,
"disabled": 0,
"noSpace": 0,
"typeId": 0,
"isDummy": 0,
"globalColumnId": 25,
"listDataId": null,
"zoneTolerence": null
},
{
"id": 1016,
"name": "No ligne",
"templateId": 213,
"tpl_fieldId": 3374,
"pageId": 0,
"isLineDefiner": 1,
"startValue": "",
"mandatoryStartValue": 0,
"stopValue": "",
"mandatoryStopValue": 0,
"defaultValue": "",
"width": 50,
"height": 238,
"x1": 1278,
"y1": 627,
"x2": 1328,
"y2": 864,
"ocrConfTolerance": 65,
"zoneTolerencePix": null,
"mask": null,
"created": "2021-06-09 13:44:33",
"createdBy": 1,
"modified": "2021-06-14 15:29:39",
"modifiedBy": 1,
"disabled": 0,
"noSpace": 0,
"typeId": 0,
"isDummy": 0,
"globalColumnId": 1,
"listDataId": null,
"zoneTolerence": null
},
{
"id": 1017,
"name": "Article",
"templateId": 213,
"tpl_fieldId": 3374,
"pageId": 0,
"isLineDefiner": 0,
"startValue": "",
"mandatoryStartValue": 0,
"stopValue": "",
"mandatoryStopValue": 0,
"defaultValue": "",
"width": 50,
"height": 238,
"x1": 1330,
"y1": 627,
"x2": 1380,
"y2": 864,
"ocrConfTolerance": 65,
"zoneTolerencePix": null,
"mask": null,
"created": "2021-06-09 13:44:33",
"createdBy": 1,
"modified": "2021-06-14 15:29:39",
"modifiedBy": 1,
"disabled": 0,
"noSpace": 0,
"typeId": 0,
"isDummy": 0,
"globalColumnId": 11,
"listDataId": null,
"zoneTolerence": null
},
{
"id": 1018,
"name": "Qte re\u00e7ue",
"templateId": 213,
"tpl_fieldId": 3374,
"pageId": 0,
"isLineDefiner": 0,
"startValue": "",
"mandatoryStartValue": 0,
"stopValue": "",
"mandatoryStopValue": 0,
"defaultValue": "",
"width": 50,
"height": 238,
"x1": 1382,
"y1": 627,
"x2": 1432,
"y2": 864,
"ocrConfTolerance": 65,
"zoneTolerencePix": null,
"mask": null,
"created": "2021-06-09 13:44:33",
"createdBy": 1,
"modified": "2021-06-14 15:29:39",
"modifiedBy": 1,
"disabled": 0,
"noSpace": 0,
"typeId": 0,
"isDummy": 0,
"globalColumnId": 8,
"listDataId": null,
"zoneTolerence": null
},
{
"id": 1019,
"name": "Prix PO",
"templateId": 213,
"tpl_fieldId": 3374,
"pageId": 0,
"isLineDefiner": 0,
"startValue": "",
"mandatoryStartValue": 0,
"stopValue": "",
"mandatoryStopValue": 0,
"defaultValue": "",
"width": 50,
"height": 238,
"x1": 1434,
"y1": 627,
"x2": 1484,
"y2": 864,
"ocrConfTolerance": 65,
"zoneTolerencePix": null,
"mask": null,
"created": "2021-06-09 13:44:33",
"createdBy": 1,
"modified": "2021-06-14 15:29:39",
"modifiedBy": 1,
"disabled": 0,
"noSpace": 0,
"typeId": 3,
"isDummy": 0,
"globalColumnId": 30,
"listDataId": null,
"zoneTolerence": null
},
{
"id": 1020,
"name": "Compte GL PO",
"templateId": 213,
"tpl_fieldId": 3374,
"pageId": 0,
"isLineDefiner": 0,
"startValue": "",
"mandatoryStartValue": 0,
"stopValue": "",
"mandatoryStopValue": 0,
"defaultValue": "",
"width": 117,
"height": 238,
"x1": 1486,
"y1": 627,
"x2": 1603,
"y2": 864,
"ocrConfTolerance": 65,
"zoneTolerencePix": null,
"mask": null,
"created": "2021-06-09 13:44:33",
"createdBy": 1,
"modified": "2021-06-14 15:29:39",
"modifiedBy": 1,
"disabled": 0,
"noSpace": 0,
"typeId": 0,
"isDummy": 0,
"globalColumnId": 33,
"listDataId": null,
"zoneTolerence": null
}
],
"content": [
{
"No projet": "0",
"No ligne": 1,
"Article": "",
"Qte re\u00e7ue": "",
"Prix PO": 0,
"Compte GL PO": ""
},
{
"No projet": "15CALL",
"No ligne": 2,
"Article": "275019734",
"Qte re\u00e7ue": 1,
"Prix PO": 20,
"Compte GL PO": "570010;570010;110499"
},
{
"No projet": "15CALL",
"No ligne": 3,
"Article": "217041984",
"Qte re\u00e7ue": 1,
"Prix PO": 135,
"Compte GL PO": "570010;570010;110499"
},
{
"No projet": "0",
"No ligne": 4,
"Article": "",
"Qte re\u00e7ue": "",
"Prix PO": 0,
"Compte GL PO": ""
}
]
I don't think that's possible. The PATH must be fixed before you join to other tables. So there's no way to make the PATH different based on values in other tables you join to.
This is similar to questions where folks want to join to a different table or a different column per row. SQL does not support that. The tables and columns must be fixed before the query begins reading any rows of data or evaluating expressions.
Instead, I recommend to expose all the content fields using separate paths, and then use a CASE expression to pick one:
SELECT jsh.cName, CASE jsh.cName
WHEN 'No projet' THEN jsc.NoProjet
WHEN 'No ligne' THEN jsc.NoLigne
WHEN 'Article' THEN jsc.Article
...
END AS qteRecu
FROM ...
CROSS JOIN JSON_TABLE(
JSON_UNQUOTE(df.calcValue), "$.content[*]"
COLUMNS(
NoProjet VARCHAR(256) PATH '$."No projet"',
NoLigne INT PATH '$."No ligne"',
Article VARCHAR(256) PATH '$.Article',
QteRecu VARCHAR(256) PATH '$."Qte re\u00e7ue"',
...)
) as jsc
Another alternative is to structure your content as a different JSON document.

JSON won't validate

I'm trying to get this to validate, it's probably a comma or formatting but I can't work it out and it's driving me insane - It doesn't seem to fail initially not sure why it does later on.
For reference: https://umod.org/plugins/server-rewards#adding-an-item
Any help would be appreciated - Thanks in advance.
{
"items": {
"lmg.m249_0": {
"shortname": "lmg.m249",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "M249",
"cost": 100,
"cooldown": 0
},
"rifle.l96_0": {
"shortname": "rifle.l96",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "L96 Rifle",
"cost": 100,
"cooldown": 0
},
"rifle.m39_0": {
"shortname": "rifle.m39",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "M39 Rifle",
"cost": 100,
"cooldown": 0
},
"rifle.lr300_0": {
"shortname": "rifle.lr300",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "LR-300 Assault Rifle",
"cost": 100,
"cooldown": 0
},
"rifle.ak_0": {
"shortname": "rifle.ak",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Assault Rifle",
"cost": 100,
"cooldown": 0
},
"pistol.python_0": {
"shortname": "pistol.python",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Python Revolver",
"cost": 100,
"cooldown": 0
},
"rocket.launcher_0": {
"shortname": "rocket.launcher",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Rocket Launcher",
"cost": 100,
"cooldown": 0
},
"multiplegrenadelauncher_0": {
"shortname": "multiplegrenadelauncher",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Multiple Grenade Launcher",
"cost": 100,
"cooldown": 0
},
"weapon.mod.lasersight_0": {
"shortname": "weapon.mod.lasersight",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Weapon Lasersight",
"cost": 100,
"cooldown": 0
},
"weapon.mod.silencer_0": {
"shortname": "weapon.mod.silencer",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Silencer",
"cost": 100,
"cooldown": 0
},
"ammo.rifle_0": {
"shortname": "ammo.rifle",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "5.56 Rifle Ammo",
"cost": 100,
"cooldown": 0
},
"ammo.rifle.hv_0": {
"shortname": "ammo.rifle.hv",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "HV 5.56 Rifle Ammo",
"cost": 100,
"cooldown": 0
},
"ammo.rifle.explosive_0": {
"shortname": "ammo.rifle.explosive",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Explosive 5.56 Rifle Ammo",
"cost": 100,
"cooldown": 0
},
"ammo.shotgun_0: {
"shortname": "ammo.shotgun",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "12 Gauge Buckshot",
"cost": 100,
"cooldown": 0
},
"ammo.shotgun.slug_0": {
"shortname": "ammo.shotgun.slug",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "12 Gauge Slug",
"cost": 100,
"cooldown": 0
},
"ammo.pistol_0": {
"shortname": "ammo.pistol",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Pistol Bullet",
"cost": 100,
"cooldown": 0
},
"ammo.pistol.hv_0": {
"shortname": "ammo.pistol.hv",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "HV Pistol Ammo",
"cost": 100,
"cooldown": 0
},
"ammo.rocket.basic_0": {
"shortname": "ammo.rocket.basic",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Rocket",
"cost": 100,
"cooldown": 0
},
"ammo.rocket.hv_0": {
"shortname": "ammo.rocket.hv",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "High Velocity Rocket",
"cost": 100,
"cooldown": 0
},
"ammo.rocket.sam_0": {
"shortname": "ammo.rocket.sam",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "SAM Ammo",
"cost": 100,
"cooldown": 0
},
"ammo.grenadelauncher.he_0": {
"shortname": "ammo.grenadelauncher.he",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "40mm HE Grenade",
"cost": 100,
"cooldown": 0
},
"ammo.grenadelauncher.buckshot_0": {
"shortname": "ammo.grenadelauncher.buckshot",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "40mm Shotgun Round",
"cost": 100,
"cooldown": 0
}
},
"kits": {},
"commands": {}
}
The error was the extra } above "kits".
{
"items": {
"lmg.m249_0": {
"shortname": "lmg.m249",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "M249",
"cost": 100,
"cooldown": 0
},
"rifle.l96_0": {
"shortname": "rifle.l96",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "L96 Rifle",
"cost": 100,
"cooldown": 0
},
"rifle.m39_0": {
"shortname": "rifle.m39",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "M39 Rifle",
"cost": 100,
"cooldown": 0
},
"rifle.lr300_0": {
"shortname": "rifle.lr300",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "LR-300 Assault Rifle",
"cost": 100,
"cooldown": 0
},
"rifle.ak_0": {
"shortname": "rifle.ak",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Assault Rifle",
"cost": 100,
"cooldown": 0
},
"pistol.python_0": {
"shortname": "pistol.python",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Python Revolver",
"cost": 100,
"cooldown": 0
},
"rocket.launcher_0": {
"shortname": "rocket.launcher",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Rocket Launcher",
"cost": 100,
"cooldown": 0
},
"multiplegrenadelauncher_0": {
"shortname": "multiplegrenadelauncher",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Multiple Grenade Launcher",
"cost": 100,
"cooldown": 0
},
"weapon.mod.lasersight_0": {
"shortname": "weapon.mod.lasersight",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Weapon Lasersight",
"cost": 100,
"cooldown": 0
},
"weapon.mod.silencer_0": {
"shortname": "weapon.mod.silencer",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Silencer",
"cost": 100,
"cooldown": 0
},
"ammo.rifle_0": {
"shortname": "ammo.rifle",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "5.56 Rifle Ammo",
"cost": 100,
"cooldown": 0
},
"ammo.rifle.hv_0": {
"shortname": "ammo.rifle.hv",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "HV 5.56 Rifle Ammo",
"cost": 100,
"cooldown": 0
},
"ammo.rifle.explosive_0": {
"shortname": "ammo.rifle.explosive",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Explosive 5.56 Rifle Ammo",
"cost": 100,
"cooldown": 0
},
"ammo.shotgun_0: {
"shortname": "ammo.shotgun",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "12 Gauge Buckshot",
"cost": 100,
"cooldown": 0
},
"ammo.shotgun.slug_0": {
"shortname": "ammo.shotgun.slug",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "12 Gauge Slug",
"cost": 100,
"cooldown": 0
},
"ammo.pistol_0": {
"shortname": "ammo.pistol",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Pistol Bullet",
"cost": 100,
"cooldown": 0
},
"ammo.pistol.hv_0": {
"shortname": "ammo.pistol.hv",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "HV Pistol Ammo",
"cost": 100,
"cooldown": 0
},
"ammo.rocket.basic_0": {
"shortname": "ammo.rocket.basic",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "Rocket",
"cost": 100,
"cooldown": 0
},
"ammo.rocket.hv_0": {
"shortname": "ammo.rocket.hv",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "High Velocity Rocket",
"cost": 100,
"cooldown": 0
},
"ammo.rocket.sam_0": {
"shortname": "ammo.rocket.sam",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "SAM Ammo",
"cost": 100,
"cooldown": 0
},
"ammo.grenadelauncher.he_0": {
"shortname": "ammo.grenadelauncher.he",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "40mm HE Grenade",
"cost": 100,
"cooldown": 0
},
"ammo.grenadelauncher.buckshot_0": {
"shortname": "ammo.grenadelauncher.buckshot",
"customIcon": null,
"amount": 1,
"skinId": 0,
"isBp": false,
"category": 1,
"displayName": "40mm Shotgun Round",
"cost": 100,
"cooldown": 0
},
"kits": {},
"commands": {}
}

Show category,sub category and its sub category hierarchy tree in nodejs-postgresql (sequelize js)

My database is as follows:
id | name | parentId
1 | Cate1 |null
2 | Cate2 | 1
3 | Cate3 | 2
My expected output is
{
id:1,
name:"Cate1",
parentId:null,
subCate:[
{
id:2,
name:"Cate2",
parentId:1,
subCate:[
{
id:3,
name:"Cate3",
parentId:2,
subCate:[]
}
]
}
]
}
And so on ...
So how to get this result.
function getNestedChildren(arr, parentId) {
var out = []
for (var i in arr) {
if (arr[i].parentId == parentId) {
var children = getNestedChildren(arr, arr[i].id)
if (children.length) {
arr[i].subCate = children
}
out.push(arr[i])
}
}
return out
}
console.log(JSON.stringify(getNestedChildren([
{id: 1, name: 'edwd', parentId: null},
{id: 2, name: 'ttt', parentId: null},
{id: 3, name: 'ooo', parentId: 1},
{id: 4, name: 'ppp', parentId: 3},
{id: 5, name: 'lll', parentId: 4},
{id: 6, name: 'mmm', parentId: 4},
{id: 7, name: 'nnn', parentId: 3},
{id: 8, name: 'zzz', parentId: 2}
], null)))
This outputs:
[
{
"id": 1,
"name": "edwd",
"parentId": null,
"subCate": [
{
"id": 3,
"name": "ooo",
"parentId": 1,
"subCate": [
{
"id": 4,
"name": "ppp",
"parentId": 3,
"subCate": [
{
"id": 5,
"name": "lll",
"parentId": 4
},
{
"id": 6,
"name": "mmm",
"parentId": 4
}
]
},
{
"id": 7,
"name": "nnn",
"parentId": 3
}
]
}
]
},
{
"id": 2,
"name": "ttt",
"parentId": null,
"subCate": [
{
"id": 8,
"name": "zzz",
"parentId": 2
}
]
}
]