Angular app reading from a nested json structure - json

I have an angular app which reads from a json that looks like the following:
[{
"category": {
"id": 40,
"name": "Category 1",
"parent": {
"id": 38,
"name": "Parent Category 1",
"parent": {
"id": 23,
"name": "Parent name",
"level": 1
},
"level": 2
},
"level": 3
},
"subcategory": {
"course_name": "Category Name 1",
"title": "Category Title",
}
},
{
"category": {
"id": 40,
"name": "Category 1",
"parent": {
"id": 38,
"name": "Parent Category 1",
"parent": {
"id": 23,
"name": "Parent name",
"level": 1
},
"level": 2
},
"level": 3
},
"subcategory": {
"course_name": "Category Name 2",
"title": "Category Title",
}
},
{
"category": {
"id": 40,
"name": "Category 1",
"parent": {
"id": 39,
"name": "Parent Category 2",
"parent": {
"id": 23,
"name": "Parent name",
"level": 1
},
"level": 2
},
"level": 3
},
"subcategory": {
"course_name": "Category Name 3",
"title": "Category Title",
}
}
]
I am trying to read this json and write it in the app such that the structure in the page looks like the following
Parent name
Parent Category 1
Category 1
Category Name 1, Category Title
Category name 2, Category Title
Parent Category 2
Category 1
Category Name 3, Category Title
How can i get this structure in angular? Here is the plunker of what i tried.

You need to summarize the data first. Then, you can repeat over the summaries to render parent level lists. Nested repeats can then conditionally display the children data.
The summary arrays (generated with a simple loop, or maybe a fancy library like lodash) might look like this:
$scope.parents = [{
"id": 23,
"name": "Parent name",
"level": 1
}]
$scope.parentCategories = [{
"id": 38,
"name": "Parent Category 1"
}, {
"id": 39,
"name": "Parent Category 2"
}]
$scope.categories = [{
"id": 40,
"name": "Category 1"
}]
Then you could use them like this:
<div ng-repeat="parent in parents">
<ul>
<li>{{parent.name}}
<ul ng-repeat="parentcategory in parentCategories">
<li>{{parentcategory.name}}
<ul ng-repeat="category in categories">
<li>{{category.name}}
<ul ng-repeat="program in programs"
ng-show="program.category.id == category.id">
<li ng-show="program.category.parent.id == parentcategory.id">
{{program.subcategory.course_name}} {{program.subcategory.title}}
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
If you want to try the code, here it is on Plunkr.

Related

Laravel Left Join ( get particular field ) and Group by ID

Using Laravel 8.12
Unable to get Printer title details in Child Array.
Order Table :
id, name, printer_id
printer Table :
id, title
Resources Table :
id. name
$resources = Resource::with('orders')
->leftJoin('orders', 'resources.id', '=', 'orders.resource_id')
->leftJoin('printers', 'orders.printer_id', '=', 'printers.id')
->select('resources.*')
->groupBy('resources.id');
Using this code i am getting below result. But missing "Title" in child array.
Current Output Result
[
{
"id": 2,
"title": "user 2",
"orders": [
{
"id": 190,
"resource_id": "2",
"printer_id": 2
},
{
"id": 193,
"resource_id": "2",
"printer_id": 3
},
]
},
{
"id": 3,
"title": "user 3",
"orders": [
{
"id": 207,
"resource_id": "3",
"printer_id": 3
},
]
},
{
"id": 4,
"title": "user 4",
"orders": [
{
"id": 466,
"resource_id": "4",
"printer_id": 4,
},
{
"id": 370,
"resource_id": "4",
"printer_id": 5,
}
]
}
]
Required Result
[
{
"id": 2,
"orders": [
{
"id": 190,
"resource_id": "2",
"title": "user 2",
"printer_id": 2
},
{
"id": 193,
"resource_id": "2",
"title": "user 3",
"printer_id": 3
},
]
},
{
"id": 3,
"orders": [
{
"id": 207,
"title": "user 3",
"resource_id": "4",
"printer_id": 3
},
]
},
{
"id": 4,
"orders": [
{
"id": 466,
"title": "user 4",
"resource_id": "4",
"printer_id": 4,
},
{
"id": 370,
"title": "user 5",
"resource_id": "4",
"printer_id": 5,
}
]
}
]
Missing Printer table "title" in child array.
You can simply run
$resources = Resource::with('orders.printer')->paginate(6);
an you will get all the data you need
[
{
"id": 2,
"title": "user 2",
"orders": [
{
"id": 190,
"resource_id": "2",
"printer_id": 2,
"printer" : {
"id" : 2,
"title" : "user 2"
}
},
{
"id": 193,
"resource_id": "2",
"printer_id": 3,
"printer" : {
"id" : 3,
"title" : "user 3"
}
}
]
}
]
Edit
You need the printer() relation declared in the model Order::class
class Order extends Model {
public function printer() {
return $this->belongsTo(Printer::class);
}
}

How can I join models in ExtJS?

In ExtJS 6.02, I would like to join 2 or more models into a single store.
1 to 1 relationship:
Given users that can only be associated with a single user detail row in DB:
"users": [
{
"id": 1,
"name": "Philip J. Fry",
"userDetail": 1
},
{
"id": 2,
"name": "Hubert Farnsworth",
"userDetail": 2
},
{
"id": 3,
"name": "Turanga Leela",
"userDetail": 3
},
{
"id": 4,
"name": "Amy Wong",
"userDetail": 4
}
]
"usersDetails": [
{
"id": 1,
"email": "jfry#a.com",
"sex": "m"
},
{
"id": 2,
"email": "hubert#a.com",
"sex": "m"
},
{
"id": 3,
"email": "leela#a.com",
"sex": "f"
},
{
"id": 4,
"email": "amy#a.com",
"sex": "m"
}
]
I would like to have this on the store:
"users": [
{
"id": 1,
"name": "Philip J. Fry",
"email": "jfry#a.com",
"sex": "m"
},
{
"id": 2,
"name": "Hubert Farnsworth",
"email": "hubert#a.com",
"sex": "m"
},
{
"id": 3,
"name": "Turanga Leela",
"email": "leela#a.com",
"sex": "f"
},
{
"id": 4,
"name": "Amy Wong",
"email": "amy#a.com",
"sex": "m"
}
]
1 to many relationship:
Given users that can have multiple posts in BD:
"users": [
{
"id": 1,
"name": "Philip J. Fry",
"userDetail": 1
},
{
"id": 2,
"name": "Hubert Farnsworth",
"userDetail": 2
},
{
"id": 3,
"name": "Turanga Leela",
"userDetail": 3
},
{
"id": 4,
"name": "Amy Wong",
"userDetail": 4
}
]
"posts": [
{
"id": 1,
"user": 1,
"title": "Post 1 title",
"body": "Post 1 body"
},
{
"id": 2,
"user": 1,
"title": "Post 2 title",
"body": "Post 2 body"
},
{
"id": 3,
"user": 2,
"title": "Post 3 title",
"body": "Post 3 body"
},
{
"id": 4,
"user": 3,
"title": "Post 4 title",
"body": "Post 4 body"
}
]
I would like to have a store containing:
"items": [
{
"id": 1,
"name": "Philip J. Fry",
"posts": [
{
"id": 1,
"title": "Post 1 title",
"body": "Post 1 body"
},
{
"id": 2,
"title": "Post 2 title",
"body": "Post 2 body"
}
]
},
{
"id": 2,
"name": "Hubert Farnsworth",
"posts": [
{
"id": 3,
"user": 2,
"title": "Post 3 title",
"body": "Post 3 body"
}
]
},
{
"id": 3,
"name": "Turanga Leela",
"userDetail": 3,
"posts": [
{
"id": 4,
"user": 3,
"title": "Post 4 title",
"body": "Post 4 body"
}
]
},
{
"id": 4,
"name": "Amy Wong",
"posts": []
}
]
Many to 1 relationship:
This is actually my actual issue, I have a DB table with multiple items that each can only match a single item in another table.
Should be same as 1 to many.
Many to many relationship:
Basicly same as 1 to many I guess?
I have seem this solution: https://fiddle.sencha.com/#fiddle/1hs9&view/editor it doesn't cover everything and maybe there's a better option.
According to Sencha support:
The concept of joining records doesn't really exist within ExtJS but
you can, by making use of renderers, access and print record
association data.
I have a simple fiddle of your example above showing you how you may
achieve this. Please note that dynamic loading of association (which
you have in your example) makes using renderers a bit tricky, but not
impossible, as the loading of the association info is asynchronous in
nature and the renderer cannot wait for the response. The work around
is to refresh the entire grid when all association stores have
finished loading.
https://fiddle.sencha.com/#fiddle/3d1v&view/editor

Angular 7 - How to display array inside of an object in HTML

I am trying to display array inside of an object in HTML. My sample JSON is like below...
I would like to display Product > ProductCategoryRelations > Category.Name in a string comma separeted like "Category 1, Category 2"
[
{
"Id": 2,
"Name": "Product 1",
"ProductCategoryRelations": [
{
"Id": 3,
"ProductId": 2,
"CategoryId": 2,
"Active": true,
"Category": {
"Id": 2,
"ParentId": 1,
"Name": "Category 1"
}
},
{
"Id": 4,
"ProductId": 2,
"CategoryId": 2,
"Active": true,
"Category": {
"Id": 2,
"ParentId": 1,
"Name": "Category 2"
}
}
],
How can I put all categories name in a string comma seperated?
What I have so fas is like below but it doesnt worrk
<dd class="col-sm-9" *ngFor="let category of product.ProductCategoryRelations">
<span>{{category.Name}}</span>
</dd>
In javascript, you would need this:
product.ProductCategoryRelations
.map(r => r.Category.Name)
.join(',')
to put it in context:
let product = {
"Id": 2,
"Name": "Product 1",
"ProductCategoryRelations": [
{
"Id": 3,
"ProductId": 2,
"CategoryId": 2,
"Active": true,
"Category": {
"Id": 2,
"ParentId": 1,
"Name": "Category 1"
}
},
{
"Id": 4,
"ProductId": 2,
"CategoryId": 2,
"Active": true,
"Category": {
"Id": 2,
"ParentId": 1,
"Name": "Category 2"
}
}
],
};
console.log(
product.ProductCategoryRelations
.map(r => r.Category.Name)
.join(',')
);
Now you can use .join(',') in Angular template syntax, but you cannot use the .map() bit. So I suspect the easiest way would be to add a utility function to your component that does this for you:
getCategoryNames(product) {
return product.ProductCategoryRelations.map(r => r.Category.Name);
}
and then do it in the template like this:
{{getCategoryNames(product).join(',')}}
If you need to do the same thing in multiple places in your app across multiple components, then I would recommend writing your own custom pipe.

How to use jq to provide ungrouped result (i.e. parent and children attributes separately)?

There is a JSON which I am getting with a script:
{
"data": [
{
"type": "physical",
"children": [
{
"children": [
{
"type": "CISCO",
"description": "test",
"id": 53,
"min_max_policy": {
"legal_hold": 0,
"name": "child 1",
"max": 60,
"min": 0
},
"name": "child 1",
"parent_id": 1,
"parent_name": "parent 1",
"system_id": 1,
"system_name": "cisco 1",
"version": "None"
},
{
"type": "CISCO",
"description": "test",
"id": 54,
"min_max_policy": {
"legal_hold": 0,
"name": "child 2",
"max": 60,
"min": 0
},
"name": "child 2",
"parent_id": 1,
"parent_name": "parent 1",
"system_id": 2,
"system_name": "cisco 1",
"version": "None"
}
],
"type": "network devices"
}
],
"machine_type": "X32",
"min_max_policy": {
"id": 1,
"name": "parent 1",
"max": 60,
"min": 0
},
"name": "parent 1",
"system_id": 1,
"system_name": "sys 1 name",
"version": "1.0"
},
{
"type": "physical",
"children": [
{
"children": [
{
"type": "HP",
"description": "test",
"id": 55,
"min_max_policy": {
"legal_hold": 0,
"name": "child 3",
"max": 60,
"min": 0
},
"name": "child 3",
"parent_id": 2,
"parent_name": "parent 2",
"system_id": 3,
"system_name": "hp 1",
"version": "None"
}
],
"type": "network devices"
}
],
"machine_type": "X32",
"min_max_policy": {
"id": 2,
"legal_hold": 0,
"name": "parent 2",
"max": 60,
"min": 0
},
"name": "parent 2",
"system_id": 2,
"system_name": "sys 2 name",
"version": "1.0"
},
{
"type": "physical",
"machine_type": "X32",
"min_max_policy": {
"id": 3,
"name": "parent 3",
"max": 60,
"min": 0
},
"name": "parent 3",
"system_id": 3,
"system_name": "sys 3 name",
"version": "1.0"
}
]
}
It has 3 parent objects and children. For example, "parent 1" has 2 children, "parent 2" has 1 and "parent 3" has 0.
How to format this JSON with jq to display it in such way:
{
"name": "child 1",
"parent_name": "parent 1",
"system_name": "cisco 1"
}
{
"name": "child 2",
"parent_name": "parent 1",
"system_name": "cisco 1"
}
{
"name": "parent 1",
"parent_name": null,
"system_name": "sys 1 name"
}
{
"name": "child 3",
"parent_name": "parent 2",
"system_name": "hp 1"
}
{
"name": "parent 2",
"parent_name": null,
"system_name": "sys 2 name"
}
{
"name": "parent 3",
"parent_name": null,
"system_name": "sys 3 name"
}
?
I have tried some options but jq is grouping parent and children. I can't find a way how to display it in the mentioned way.
Except for the ordering, the following jq program produces the desired output, as shown below:
..
| select(.name? and .system_name?)
| {name, parent_name, system_name}
Transcript
$ jq -f program.jq input.json
{
"name": "parent 1",
"parent_name": null,
"system_name": "sys 1 name"
}
{
"name": "child 1",
"parent_name": "parent 1",
"system_name": "cisco 1"
}
{
"name": "child 2",
"parent_name": "parent 1",
"system_name": "cisco 1"
}
{
"name": "parent 2",
"parent_name": null,
"system_name": "sys 2 name"
}
{
"name": "child 3",
"parent_name": "parent 2",
"system_name": "hp 1"
}
{
"name": "parent 3",
"parent_name": null,
"system_name": "sys 3 name"
}

Group similar items in array of objects

Hello i have the following JSON:
[
{
"name": "Donation",
"collection": {
"name": "Donation Company 1",
"collection": {
"id": 1,
"category": "Donation",
"name": "Some Donation",
"price": 10,
"description": "Hahahaha",
"company": "Donation Company 1"
}
}
},
{
"name": "Donation",
"collection": {
"name": "Donation Company 1",
"collection": {
"id": 2,
"category": "Donation",
"name": "Another Donation",
"price": 50,
"description": "LoL",
"company": "Donation Company 1"
}
}
},
{
"name": "Insurance Company 1",
"collection": {
"name": "Hehe",
"collection": {
"id": 3,
"category": "Insurance",
"name": "Lorem Ipsum Solor",
"price": 25,
"description": "Lmao",
"company": "Insurance Company 1"
}
}
},
{
"name": "Insurance Company 2",
"collection": {
"name": "Donation Company 1",
"collection": {
"id": 5,
"category": "Insurance",
"name": "Sample Extra",
"price": 500,
"description": "Lorem ipsum dolor",
"company": "Insurance Company 2"
}
}
}
]
I'm having trouble trying to group the similar items together, as in all items in the same category appear in the same category array.
And in each category all items that have the same company end up in the same company array.
This is an example what i am trying to accomplish, i used an online editor to construct the JSON:
expected-json-output-when-saved
I used the laravel collect() helper function to construct my array of objects, i have tried several combinations in foreach loops and have been at it for hours but have still not been able to get the expected JSON returned.
Assuming you json_decode() that JSON string and stored it in a $json variable, you can do the following:
$collection = collect($json);
$collection = $collection->groupBy('collection.collection.category');
Dump the $collection variable to see the result.