I have three sample JSON file that I need to loop through. I was able to do two of them already, but the third one is missing. The idea is to go through it using the same logic as the first two.
Example 1 (Sales header)
Controller
$data1 = '[{
"T": {
"HD": {
"HD01": "1",
"HD06": "20201006033942",
"HD08": "3736803"
}
}
},
{
"T": {
"HD": {
"HD01": "2",
"HD06": "20201006035419",
"HD08": "7523658"
}
}
}]';
$json = json_decode($data1, true);
$head = collect($json)->map(function ($value) {
return $value["T"]["HD"];
});
return view('dashboard.book.index', [
'head' => $head
]);
Blade
<table class="table">
<tr>
<td> HD01</td>
<td> HD02</td>
<td> HD03</td>
<td> HD04</td>
<td> HD05</td>
<td> HD06</td>
</tr>
#foreach ($head as $value)
<tr>
<td>{{ $value['HD01'] }}</td>
<td>{{ $value['HD02'] }}</td>
<td>{{ $value['HD03'] }}</td>
<td>{{ $value['HD04'] }}</td>
<td>{{ $value['HD05'] }}</td>
<td>{{ $value['HD06'] }}</td>
</tr>
#endforeach
</table>
Result
Header
Example 2 (Detail of sale)
Controller
$data2 = '[{
"T": {
"SIEL" : {
"SIE" : [
{
"sequenceNumber" : 0,
"itemId" : "3010",
"itemDescription" : "BAN VACCINE COSTELLET",
"unitAmount" : 29950,
"quantity" : 1,405,
"subTotalAmount" : 42080,
"discountAmount" : 0,
"totalAmount" : 42080
},
{
"sequenceNumber" : 1,
"itemId" : "1010",
"itemDescription" : "CROLETA COOKIE",
"unitAmount" : 4800,
"quantity" : 0.605,
"subTotalAmount" : 2904,
"discountAmount" : 0,
"totalAmount" : 2904
}
]
}
}
},
{
"T": {
"SIEL" : {
"SIE" : [
{
"sequenceNumber" : 0,
"itemId" : "3010",
"itemDescription" : "BAN VACCINE COSTELLET",
"unitAmount" : 29950,
"quantity" : 1,405,
"subTotalAmount" : 42080,
"discountAmount" : 0,
"totalAmount" : 42080
},
{
"sequenceNumber" : 1,
"itemId" : "1010",
"itemDescription" : "CROLETA COOKIE",
"unitAmount" : 4800,
"quantity" : 0.605,
"subTotalAmount" : 2904,
"discountAmount" : 0,
"totalAmount" : 2904
}
]
}
}
}
]';
$json = json_decode($data2, true);
$details = collect($json)->map(function ($value) {
return $value["T"]["SIEL"]["SIE"];
});
return view('dashboard.book.index', [
'details' => $details
]);
Blade
<table class="table">
<tr>
<td> sequenceNumber</td>
<td> itemId</td>
<td> itemDescription</td>
<td> unitAmount</td>
<td> quantity</td>
<td> subTotalAmount</td>
<td> discountAmount </td>
<td> totalAmount </td>
</tr>
#foreach ($details as $items)
#foreach ($items as $key => $value)
<tr>
<td>{{ $value['sequenceNumber'] }}</td>
<td>{{ $value['itemId'] }}</td>
<td>{{ $value['itemDescription'] }}</td>
<td>{{ $value['unitAmount'] }}</td>
<td>{{ $value['quantity'] }}</td>
<td>{{ $value['subTotalAmount'] }}</td>
<td>{{ $value['discountAmount'] }}</td>
<td>{{ $value['totalAmount'] }}</td>
</tr>
#endforeach
#endforeach
</table>
Result
Details
Example 3 (Header more detail)
$data3 = '[
{
"T":{
"HD":{
"HD01":"1",
"HD02":"20201007",
"HD03":"1001",
"HD04":"15",
"HD05":140,
"HD06":"20201007062511",
"HD07":"",
"HD08":"3514401",
"HD09":"PYG",
"HD10":"PYG",
"HD11":"00000 A000005",
"HD12":"",
"HD13":"",
"HD14":"",
"HD15":"",
"HD16":"",
"HD17":"Insufficient Funds",
"HD18":"",
"HD19":"",
"HD20":"",
"HD21":0,
"HD22":"ICAE",
"HD23":false,
"HD24":false,
"HD26":0
},
"SIEL":{
"SIE":[
{
"sequenceNumber":0,
"itemId":"1159",
"itemDescription":"BREAD FOR PANCHO",
"unitAmount":3500,
"quantity":0.001,
"subTotalAmount":4,
"discountAmount":0,
"totalAmount":4
},
{
"sequenceNumber":1,
"itemId":"2098",
"itemDescription":"HAPPY DAY CAKE",
"unitAmount":28950,
"quantity":0.001,
"subTotalAmount":29,
"discountAmount":0,
"totalAmount":29
}
]
}
}
},
{
"T":{
"HD":{
"HD01":"1",
"HD02":"20201007",
"HD03":"1001",
"HD04":"15",
"HD05":141,
"HD06":"20201007063358",
"HD07":"",
"HD08":"3514401",
"HD09":"PYG",
"HD10":"PYG",
"HD11":"0010580000125",
"HD12":"",
"HD13":"",
"HD14":"",
"HD15":"",
"HD16":"",
"HD17":"",
"HD18":"",
"HD19":"",
"HD20":"",
"HD21":16100,
"HD22":"ICAE",
"HD23":false,
"HD24":false,
"HD26":-47
},
"SIEL":{
"SIE":[
{
"sequenceNumber":0,
"itemId":"1110",
"itemDescription":"STICK WITHOUT ANISE",
"unitAmount":9100,
"quantity":1.115,
"subTotalAmount":10147,
"discountAmount":0,
"totalAmount":10147
},
{
"sequenceNumber":1,
"itemId":"7841503001513",
"itemDescription":"TRIPACK CRACKER CLASS",
"unitAmount":6000,
"quantity":1,
"subTotalAmount":6000,
"discountAmount":0,
"totalAmount":6000
}
}
]
}
}
}
]';
$json = json_decode($data3, true);
$tickets = collect($json)->map(function ($value) {
return ????
});
So, I don't know how to put it in the return so that the data is sent and go through it as a single combined table
Example of how it should be:
Table
One possible solution would be to obtain all the keys from the JSON string and store those as a separate variable, then do something similar for the actual data.
So for example, to obtain all the keys from your JSON you could do the following:
$keys =
collect(json_decode($data)[0]->T->HD)
->merge(collect(json_decode($data)[0]->T->SIEL->SIE[0]))
->keys();
What this does is produce an array of just the JSON keys you're interested in making iterating over the keys nice and simple.
#foreach ($keys as $key)
{{ $key }}
#endforeach
As for your data, it would be a similar process but instead we're focusing on the values of the JSON rather than the keys.
$data = collect(json_decode($data))->map(function ($element) {
return collect($element->T->HD)->merge(collect(['SIE' => $element->T->SIEL->SIE]));
});
This results in a (somewhat flattened) collection of your data with all HD prefixed keys at the top level of each collection element and a sub collection of SIE elements.
[
"HD01" => 1,
"HD02" => 2,
...
"SIE" => [
[
"sequenceNumber":0,
"itemId":"1110",
"itemDescription":"STICK WITHOUT ANISE",
...
],
...
]
]
From here it should be a straight forward process of iterating over the data in your blade view to ouput it.
A functional example here.
Related
I am working with MongoDB and so far I have been able to loop through the following JSON correctly with the ability to manipulate the data to display.
controller
$json = '[{
"T": {
"HD": {
"HD01": "1",
"HD06": "20201006033942",
"HD08": "3736803"
}
}
},
{
"T": {
"HD": {
"HD01": "1",
"HD06": "20201006035419",
"HD08": "3736803"
}
}
}]'
$keysToRemove = ['HD01', 'HD06'];
$data = collect(json_decode($data, true))
->flatten(2)
->map(function ($array, $key) use ($keysToRemove) {
foreach ($keysToRemove as $key) {
if (array_key_exists($key, $array)) {
unset($array[$key]);
}
}
return $array;
});
return view('dashboard.book.index', [
'data' => $data
]);
Blade
<table>
<tr>
#foreach ($data->first() as $key => $value)
<th>{{ $key }}</th>
#endforeach
</tr>
#foreach ($data as $items)
<tr>
#foreach ($items as $key => $value)
<td>{{ $value }}</td>
#endforeach
</tr>
#endforeach
</table>
result
Table
Now, now I must go through another one that has an array inside it, and which is made up as follows:
controller
$data = '[{
"T": {
"SIEL" : {
"SIE" : [
{
"sequenceNumber" : 0,
"itemId" : "3010",
"itemDescription" : "BAN VACCINE COSTELLET",
"unitAmount" : 29950,
"quantity" : 1,405,
"subTotalAmount" : 42080,
"discountAmount" : 0,
"totalAmount" : 42080
},
{
"sequenceNumber" : 1,
"itemId" : "1010",
"itemDescription" : "CROLETA COOKIE",
"unitAmount" : 4800,
"quantity" : 0.605,
"subTotalAmount" : 2904,
"discountAmount" : 0,
"totalAmount" : 2904
}
]
}
}
}]';
How do I go through it following the logic of the first one, to obtain the 'SIE' data?
It is a similar principle to your previous question. Decode your JSON to an associative array, convert to a collection, flatten it and work with the result.
$sieData = collect(json_decode($data, true))->flatten(3)->collapse();
return view('view.blade.php', compact('sieData'));
The value of sieData is an array of associated arrays. You already have how to loop over such a structure in the example code you provided in your question.
i have this json file :
{
"id": 1276,
"etabName": "YAssineDev",
"etabType": "OUR_SCHOOL",
"users": [
{
"id": 12,
"username": "YassineDev",
"firstName": "yassine",
"lastName": "messaoud",
"active": true,
"payant": false,
"creatdateTime": "2021-06-08",
"roles": [
{
"id": 2,
"roleName": "ADMIN_USER",
"description": "admin user"
}
]
}
]
},
i want to display the username of the users tab in the html,
i have tried with *ngFor:
<tbody>
<tr *ngFor="let t of tabs.users">
<td>{{ t.username }}</td>
</tr>
</tbody>
getMethod
dataEtabUser() {
this.cr.getdataEtab().subscribe(data=> {
this.tabs = data
})
}
ngOnInit
this.dataEtabUser()
but nothing displayed
Assuming the dataEtabUser() works correctly
<div *ngFor="let t of tabs">
<tbody *ngFor="let user of t.users">
<tr *ngFor="let data of user">
<td>{{ data.username }}</td>
</tr>
</tbody>
</div>
There are two orders in this json array.
I need to pull the quantity and price from one internal array (product_id) and from another (name) product name
the pivot array is unknown to me, and it is not complete
I try this:
<template v-for="order in orders">
<tr>
<td>{{ order.order_id }}</td>
<td>
<span v-for="product_id in order.product_id">
<span v-for="name in order.name">
{{ name.name }} -
</span>
{{ product_id.quantity }}pc.
Price: {{ product_id.price }}
</span>
</td>
</tr>
</template>
but I get the data in the wrong order:
Product_8 - Product_21 - Product_30-1 pc. Price: 141
Product_8 - Product_21 - Product_30-2 pc. Price: 509
Product_8 - Product_21 - Product_30-1 pc. Price: 399
Product_1 - Product_11 - Product_20-3 pc. Price: 320
Product_1 - Product_11 - Product_20-2 pc. Price: 953
Product_1 - Product_11 - Product_20-1 pc. Price: 911
This is my original json array:
[
{
"order_id":1,
"status":20,
"partner_name":"McLaughlin",
"product_id":[
{
"id":1,
"order_id":1,
"product_id":8,
"quantity":1,
"price":141
},
{
"id":2,
"order_id":1,
"product_id":30,
"quantity":2,
"price":509
},
{
"id":3,
"order_id":1,
"product_id":21,
"quantity":1,
"price":399
}
],
"name":[
{
"id":8,
"name":"Product_8",
"price":141,
"pivot":{
"order_id":1,
"product_id":8
}
},
{
"id":21,
"name":"Product_21",
"price":399,
"pivot":{
"order_id":1,
"product_id":21
}
},
{
"id":30,
"name":"Product_30",
"price":509,
"pivot":{
"order_id":1,
"product_id":30
}
}
]
},
{
"order_id":2,
"status":10,
"partner_name":"Grimes",
"product_id":[
{
"id":4,
"order_id":2,
"product_id":1,
"quantity":3,
"price":320
},
{
"id":5,
"order_id":2,
"product_id":11,
"quantity":2,
"price":953
},
{
"id":6,
"order_id":2,
"product_id":20,
"quantity":1,
"price":911
}
],
"name":[
{
"id":1,
"name":"Product_1",
"price":320,
"pivot":{
"order_id":2,
"product_id":1
}
},
{
"id":11,
"name":"Product_11",
"price":953,
"pivot":{
"order_id":2,
"product_id":11
}
},
{
"id":20,
"name":"Product_20",
"price":911,
"pivot":{
"order_id":2,
"product_id":20
}
}
]
},
Ideally, this would be the case, but the number of products in the order may vary:
<td>{{ order.name[0].name }} </br>
{{ order.product_id[0].quantity }}pc. </br>
Price: {{ order.product_id[0].price }}</td>
<td>{{ order.name[1].name }} </br>
{{ order.product_id[1].quantity }}pc. </br>
Price: {{ order.product_id[1].price }}</td>
<td>{{ order.name[2].name }} </br>
{{ order.product_id[2].quantity }}pc. </br>
Price: {{ order.product_id[2].price }}</td>
Tell me how to correctly extract such data in Vue?
In general, the table you want is not so semantic (Anyway this is not the issue of the Q).
iterating throw objects
This issue related to iterating throw objects in general (Not specific to vue).
https://v2.vuejs.org/v2/guide/list.html
The idea here is to use dot notation and nested loop (google "Accessing JSON Data" to get the idea/concepts - one example: Accessing JSON data).
Very useful her to use console.log to "learn" your data structure:
console.log(orders[0].name[0].pivot.name); /* return pivot name for order 1 */
If console.log render undefined - You have an error accessing the object.
Loop - get the pivot:
<template v-for="order in orders">
<p>{{order.name[0].pivot.name}}</p>
</template>
Nested loop
Get price
<!-- outer loop throw orders -->
<template v-for="order in orders">
<!-- inner loop throw product_id-->
<tr v-for="(item, index) in order.product_id">
<td>
<b>price:</b> {{ item.price }}$
</td>
</tr>
</template>
Again take these ideas and create a more readable & valid table.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table
My advice - First outline the table by plain HTML - then move these ideas to Vue.
Snippet example (Not semantic table):
var orders = [
{
"order_id":"order_id_1",
"status":20,
"partner_name":"McLaughlin",
"name":[
{
"id":8,
"name":"Order name one",
"price":141,
"pivot":{
"order_id":1,
"product_id":8
}
}
],
"product_id":[
{
"name": "nike shoes",
"id":1,
"quantity":1,
"price":141
},
{
"name": "adidas shoes",
"id":2,
"quantity":2,
"price":509
}
]
},
{
"order_id": "order_id_2",
"status":10,
"partner_name":"Grimes",
"name":[
{
"id":8,
"name":"Order name two",
"price":141,
"pivot":{
"order_id":1,
"product_id":8
}
}
],
"product_id":[
{
"name": "puma shoes",
"id":4,
"quantity":3,
"price":320
},
{
"name": "asics shoes",
"id":5,
"quantity":2,
"price":953
},
{
"name": "NB shoes",
"id":6,
"quantity":1,
"price":911
}
],
}
]
var example1 = new Vue({
el: '#example-1',
parentMessage: 'Parent',
data: {
orders: orders
}
})
<link href="https://unpkg.com/purecss#1.0.1/build/pure-min.css" rel="stylesheet"/>
<table id="example-1" style="width: 100%;" class="pure-table pure-table-bordered pure-table-striped">
<!-- outer loop -->
<template v-for="order in orders">
<tr>
<th style="background: red; color: white;">{{order.name[0].name}}</th>
</tr>
<!-- inner loop -->
<tr v-for="(item, index) in order.product_id">
<td>
<p><b>Product:</b> {{ item.name }}</p>
<p><b>item price:</b> {{ item.price }}$</p>
<p><b>quantity:</b> {{ item.quantity }}</p>
<p><b>sum:</b><v-model style="color: green;" v-model.number="price = item.quantity * item.price">{{price}}$</v-model>
<p>{{order.name[0].pivot.name}}</p>
</td>
</tr>
<br>
</template>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
I have an AngularJS variable var vm = this; which contains a big JSON format data:
vm.data = {
"sites": [{
"siteName": "A",
"countries": [{
"country": "DE",
"servers": [{
"serverType": "master",
"URL": ""
},{
"serverType": "slave",
"URL": ""
}]
}]
},{
"siteName": "B",
"countries": [{
"country": "IT",
"servers": [{
"serverType": "master",
"URL": ""
},{
"serverType": "slave",
"URL": ""
}]
},{
"country": "NL",
"servers": [{
"serverType": "master",
"URL": ""
},{
"serverType": "slave",
"URL": ""
}]
}]
}]
};
I want to put this data in a table
I use "c" because of the the "controller (which is the name of my controller) as c".
<tr ng-repeat="site in c.data.sites">
<td>{{ site.siteName }}</td>
<td>{{ site.countries }}</td>
<td>{{ site.countries.name }}</td>
</tr>
The first td works perfectly, the second displays everything that is contained in the countries set, and the last doesn’t display anything.
I tried to declare vm.data.sites.countries, but it failed.
Can you shed some light on this?
Your countries is an array, so if you want to list every country you can access every name of the country objects (your name attribute for a country object is country) with a new loop (ng-repeat).
<tr ng-repeat="site in c.data.sites">
<td>{{ site.siteName }}</td>
<td>{{ site.countries }}</td>
<td>
<span ng-repeat="country in site.countries>
{{country.country}}
<span ng-if="!$last">, </span>
</span>
</td>
</tr>
Well you're not really referencing your keys appropriately.
<tr ng-repeat="site in c.data.sites">
<td>{{ site.siteName }}</td>
<td>
<span ng-repeat="country in site.countries">
{{ country.country }}
<span ng-hide="$last">, </span>
</span>
</td>
</tr>
I have json that looks like this :
[
{
"date": "25/06/2015",
"details": [
{
"p": "AM",
"b": "2500"
},
{
"p": "JL",
"b": "300"
}
]
},
{
"date": "24/06/2015",
"details": [
{
"p": "AM",
"b": "2300"
},
{
"p": "JL",
"b": "1300"
}
]
}
]
I want to write the data to an html table using angularjs, but I want the value of date.details.p to determine which column the value of date.details.b should go in. So, for example the value date.details.b will always go in column 2 if date.details.p = 'AM'.
The JSON data will not always contain data that would relate to each column, nor can the order of the details array be guaranteed.
Any ideas gratefully received.
EDIT
The expected output would be
Date AM JL
25/06/2015 2500 300
24/06/2015 2300 1300
Based on the limited info I can suggest you can use ngShow.
<tr>
<td class="ColumnTwo">
<span data-ng-show="checkAM(date)">{{date.details.p}}</span>
</td>
</tr>
In the function checkAM you can check if date.details.p == "AM"
Based on the situation you can use
ngSwitch
ngIf
Also check out https://stackoverflow.com/a/15810462/2489860
Try this:
<table>
<tr>
<th>Date</th>
<th>AM</th>
<th>JL</th>
</tr>
<tr ng-repeat="item in data">
<td>{{ item.date }}</td>
<td ng-repeat="detail in item.details">
<span ng-show="detail.p=='AM' && $index == 0">{{ detail.b }}</span>
<span ng-show="detail.p=='JL' && $index == 1">{{ detail.b }}</span>
</td>
</tr>
</table>
You can see and run the complete code below:
angular.module('app', [])
.controller('ctrl', function ($scope) {
$scope.data = [
{
"date": "25/06/2015",
"details": [
{
"p": "AM",
"b": "2500"
},
{
"p": "JL",
"b": "300"
}
]
},
{
"date": "24/06/2015",
"details": [
{
"p": "AM",
"b": "2300"
},
{
"p": "JL",
"b": "1300"
}
]
}
];
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-app="app">
<div ng-controller="ctrl">
<table>
<tr>
<th>Date</th>
<th>AM</th>
<th>JL</th>
</tr>
<tr ng-repeat="item in data">
<td>{{ item.date }}</td>
<td ng-repeat="detail in item.details">
<span ng-show="detail.p=='AM' && $index == 0">{{ detail.b }}</span>
<span ng-show="detail.p=='JL' && $index == 1">{{ detail.b }}</span>
</td>
</tr>
</table>
</div>
</body>
</html>