Group Laravel collection by the given key - arrays

in Laravel I want to change response if same user array have multiple response
I get a response with this function
controller.php
public function index(){
$reports = Report::all();
return $this->sendResponse($reports->toArray(), 'User Reports successfully.');
}
This is my response
{
"success": true,
"data": [
{
"id": 66,
"cuid": 20,
"name": "my1",
"created_at": "2018-03-09 00:00:00",
"updated_at": "2018-03-09 00:00:00",
"time": "07:19 PM",
"status": "D"
},
{
"id": 65,
"cuid": 20,
"name": "my1",
"created_at": "2018-03-07 00:00:00",
"updated_at": "2018-03-07 00:00:00",
"time": "07:39 PM",
"status": "D"
},
{
"id": 64,
"cuid": 21,
"name": "my2",
"created_at": "2018-03-02 00:00:00",
"updated_at": "2018-03-05 00:00:00",
"time": "07:01 PM",
"status": "D"
},
{
"id": 63,
"cuid": 20,
"name": "my2",
"created_at": "2018-03-02 00:00:00",
"updated_at": "2018-03-02 00:00:00",
"time": "06:44 PM",
"status": "D"
}
],
"message": "User Reportsssss successfully."
}
This is fine my problem is i have 4 array with 2 user insted showing that way i want to show like this
{
"success": true,
"data": [
my1:{
{
"id": 66,
"cuid": 20,
"name": "my1",
"created_at": "2018-03-09 00:00:00",
"updated_at": "2018-03-09 00:00:00",
"time": "07:19 PM",
"status": "D"
}
{
"id": 65,
"cuid": 20,
"name": "my1",
"created_at": "2018-03-07 00:00:00",
"updated_at": "2018-03-07 00:00:00",
"time": "07:39 PM",
"status": "D"
}
},
my2:{
{
"id": 63,
"cuid": 21,
"name": "my2",
"created_at": "2018-03-07 00:00:00",
"updated_at": "2018-03-07 00:00:00",
"time": "07:39 PM",
"status": "D"
}
{
"id": 64,
"cuid": 21,
"name": "my2",
"created_at": "2018-03-02 00:00:00",
"updated_at": "2018-03-05 00:00:00",
"time": "07:01 PM",
"status": "D"
}
}
],
"message": "User Reportsssss successfully."
}
How to achive this if same user comes under single array

The ideal way to do this would be by using collection pipelines. Your original controller method would become the following;
public function index(){
$reports = Report::all();
return $this->sendResponse($reports->groupBy('name')->toArray(), 'User Reports successfully.');
}
The groupBy method will split the collection results out into other collections, grouped by the provided column. Because the toArray() method cascades, you'll get a nice array back.

You need to loop through the result and modify it as per your requirement.I have tested the below code its working fine. Try using it.
$reports = $reports->toArray();
$finalArray = [];
foreach($reports as $key=>$value) {
$name = $value['name'];
$finalArray[$name][] = $value;
}
return $this->sendResponse($finalArray, 'User Reports successfully.');
Thanks.

Related

How to scroll to a particular section of the data fetched from an API while filtering the data on some parameter?

I am calling an API from a server, and I am getting this as a response. A part of the data I am getting -
{
"id": 322854,
"date": "2022-09-20T18:00:00+00:00",
"time": "18:00",
"timestamp": 1663696800,
"timezone": "UTC",
"stage": null,
"week": null,
"status": {
"long": "Game Finished",
"short": "FT",
"timer": null
},
"league": {
"id": 9,
"name": "French Cup",
"type": "cup",
"season": 2022,
"logo": "https://media-2.api-sports.io/basketball/leagues/9.png"
},
"country": {
"id": 4,
"name": "France",
"code": "FR",
"flag": "https://media-2.api-sports.io/flags/fr.svg"
},
"teams": {
"home": {
"id": 22,
"name": "Boulazac",
"logo": "https://media-2.api-sports.io/basketball/teams/22.png"
},
"away": {
"id": 2294,
"name": "CEP Lorient",
"logo": "https://media-2.api-sports.io/basketball/teams/2294.png"
}
},
"scores": {
"home": {
"quarter_1": 16,
"quarter_2": 12,
"quarter_3": 21,
"quarter_4": 26,
"over_time": null,
"total": 75
},
"away": {
"quarter_1": 9,
"quarter_2": 16,
"quarter_3": 19,
"quarter_4": 23,
"over_time": null,
"total": 67
}
}
}
{
"id": 322854,
"date": "2022-09-20T18:00:00+00:00",
"time": "18:00",
"timestamp": 1663696800,
"timezone": "UTC",
"stage": null,
"week": null,
"status": {
"long": "Game Not Started",
"short": "NS",
"timer": null
},
"league": {
"id": 9,
"name": "French Cup",
"type": "cup",
"season": 2022,
"logo": "https://media-2.api-sports.io/basketball/leagues/9.png"
},
"country": {
"id": 4,
"name": "France",
"code": "FR",
"flag": "https://media-2.api-sports.io/flags/fr.svg"
},
"teams": {
"home": {
"id": 22,
"name": "Boulazac",
"logo": "https://media-2.api-sports.io/basketball/teams/22.png"
},
"away": {
"id": 2294,
"name": "CEP Lorient",
"logo": "https://media-2.api-sports.io/basketball/teams/2294.png"
}
},
"scores": {
"home": {
"quarter_1": 16,
"quarter_2": 12,
"quarter_3": 21,
"quarter_4": 26,
"over_time": null,
"total": 75
},
"away": {
"quarter_1": 9,
"quarter_2": 16,
"quarter_3": 19,
"quarter_4": 23,
"over_time": null,
"total": 67
}
}
}
There are a bunch of such objects in an array each having a different fixture. As you can see that status?.short === "NS" in one while the other is status?.short === "FT". Now, I want to filter the data using these properties.
<div className="fixturesTab-container">
<div className="fixturesTab-container__header">
<h4>Fixtures</h4>
</div>
<div className="fixturesTab-container__body">
{fixtures.map((fixture) => (
<div
key={fixture?.id}
className="fixturesTab-container__body__box"
>
......
</div>
))}
</div>
</div>
I want the data to be displayed in such a manner that when the user browse to that page and the API is being fetched, eventhough the entire data (fixtures) is being displayed in the page. I want the fixtures that have not yet started, i.e has the property of status?.short === "NS", to be displayed in the window that is visible to the user. And the rest data can be acquired by either scrolling up, which will have the fixtures that have been completed, or by scrolling down which will have the fixtures that have not yet been started.
If, I am unable to understand what I want properly, then you can check out this page . This is exactly what I am planning to achieve.

Flutter Create dynamic widget from dynamic json response

companyList = data['fields'][0]['choices'];
if (companyList.length != 0) {
int val;
for (val = 0; val < companyList.length; val++) {
final controller = TextEditingController();
final field = xTextfield(
txtlabel: "Values",
iconfield: bookmarksIcon,
);
setState(() {
_controllers.add(controller);
_fields.add(field);
});
}
}
But this works only if json response is same when it changes and Array object is differnet i got error here is my json that will be different everytime e.g
"inputtype": "dropdown", will make a dropdown widget and all data will be put into it and so on
{ "fields": [ { "id": 31, "name": "make", "isrequired": "required", "valuetype": "text", "priority": 1, "inputtype": "dropdown", "max_min": [], "rangeable": "false", "choices": [ { "id": 46, "name": "Samsung", "categoryextrafield_id": 31, "created_at": "2021-12-29T01:30:47.000000Z", "updated_at": "2021-12-29T01:30:47.000000Z", "priority": 10 }, { "id": 47, "name": "Dell", "categoryextrafield_id": 31, "created_at": "2021-12-29T01:30:52.000000Z", "updated_at": "2021-12-29T01:30:52.000000Z", "priority": 20 }, { "id": 48, "name": "IBM", "categoryextrafield_id": 31, "created_at": "2021-12-29T01:31:09.000000Z", "updated_at": "2021-12-29T01:31:09.000000Z", "priority": 30 }, { "id": 49, "name": "Acer", "categoryextrafield_id": 31, "created_at": "2021-12-29T01:31:24.000000Z", "updated_at": "2021-12-29T01:31:24.000000Z", "priority": 40 } ], "available": [] }, { "id": 32, "name": "model", "isrequired": "required", "valuetype": "text", "priority": 2, "inputtype": "textfield", "max_min": [], "rangeable": "false", "choices": [], "available": [ { "model": "a51" }, { "model": "y9s" }, { "model": "a31" }, { "model": "yS10" }, { "model": "Y10S" }, { "model": "A551" }, { "model": "node8" }, { "model": "s9" }, { "model": null }, { "model": "2021" }, { "model": "2020" }, { "model": "2010" }, { "model": "Civic" }, { "model": "2019" }, { "model": "Daewooy9" }, { "model": "corei5" }, { "model": "corei9" }, { "model": "corei3" }, { "model": "corei11" } ] }, { "id": 29, "name": "features", "isrequired": "required", "valuetype": "text", "priority": 3, "inputtype": "checkbox", "max_min": [], "rangeable": "false", "choices": [ { "id": 41, "name": "Bluetooth", "categoryextrafield_id": 29, "created_at": "2021-12-29T01:19:00.000000Z", "updated_at": "2021-12-29T01:19:00.000000Z", "priority": 1 }, { "id": 42, "name": "Fingerprint", "categoryextrafield_id": 29, "created_at": "2021-12-29T01:19:10.000000Z", "updated_at": "2021-12-29T01:19:10.000000Z", "priority": 10 }, { "id": 43, "name": "LedDisplay", "categoryextrafield_id": 29, "created_at": "2021-12-29T01:19:35.000000Z", "updated_at": "2021-12-29T01:19:35.000000Z", "priority": 15 } ], "available": [] }, { "id": 30, "name": "condition", "isrequired": "required", "valuetype": "text", "priority": 4, "inputtype": "radiobutton", "max_min": [], "rangeable": "false", "choices": [ { "id": 44, "name": "Used", "categoryextrafield_id": 30, "created_at": "2021-12-29T01:20:31.000000Z", "updated_at": "2021-12-29T01:20:31.000000Z", "priority": 10 }, { "id": 45, "name": "New", "categoryextrafield_id": 30, "created_at": "2021-12-29T01:20:38.000000Z", "updated_at": "2021-12-29T01:20:38.000000Z", "priority": 20 } ], "available": [] } ] }
You can use the Dynamic Widget package.
Just pass the widget as JSON data from the server and use a FutureBuilder to build it when your data arrives.
You will also need to change your JSON data accordingly.

Convert array structure from first array to second

This is my multi dimensional array.
Output should be in array2 structure.
I have tried many ways covert above array in easy but all came up with bulky code and lots of iteration.
Is there any easy way to do so?
I am a new in angular and JavaScript.
var array1=[
{
"id": 1,
"name": "Johny",
"category": [
{
"id": 12,
"name": "GUI",
"status": {
"id": 123,
"status": "working",
"name": "GUI"
}
},
{
"id": 13,
"name": "GFX",
"status": {
"id": 124,
"status": "working",
"name": "GFX"
}
},
{
"id": 14,
"name": "UI",
"status": {
"id": 125,
"status": "working",
"name": "UI"
}
}
]
},
{
"id": 2,
"name": "Paul",
"category": [
{
"id": 21,
"name": "GUI",
"status": {
"id": 212,
"status": "Progress",
"name": "GUI"
}
},
{
"id": 22,
"name": "GFX",
"status": {
"id": 221,
"status": "working",
"name": "GFX"
}
},
{
"id": 23,
"name": "DM",
"status": {
"id": 231,
"status": "done",
"name": "DM"
}
}
]
}
]
I want to change into this array2.
var array2=[
{
"id": 1,
"name": "Johny",
"category": [
{
"id": 12,
"name": "GUI",
"data": [
{
"id": 12,
"name": "GUI",
"status": {
"id": 123,
"status": "working",
"name": "GUI"
}
},
{
"id": 21,
"name": "GUI",
"status": {
"id": 212,
"status": "Progress",
"name": "GUI"
}
}
]
},
{
"id": 13,
"name": "GFX",
"data": [
{
"id": 13,
"name": "GFX",
"status": {
"id": 124,
"status": "working",
"name": "GFX"
}
},
{
"id": 22,
"name": "GFX",
"status": {
"id": 221,
"status": "working",
"name": "GFX"
}
}
]
},
{
"id": 14,
"name": "UI",
"data": [
{
"id": 14,
"name": "UI",
"status": {
"id": 125,
"status": "working",
"name": "UI"
}
},
//null data if not in first
{}
]
},
{
"id": 23,
"name": "DM",
"data": [
//null data if not in first
{},
{
"id": 23,
"name": "DM",
"status": {
"id": 231,
"status": "done",
"name": "DM"
}
}
]
}
]
},
{
"id": 2,
"name": "Paul",
"category": [
{
"id": 21,
"name": "GUI",
"data": [
{
"id": 12,
"name": "GUI",
"status": {
"id": 123,
"status": "working",
"name": "GUI"
}
},
{
"id": 21,
"name": "GUI",
"status": {
"id": 212,
"status": "Progress",
"name": "GUI"
}
}
]
},
{
"id": 22,
"name": "GFX",
"data": [
{
"id": 13,
"name": "GFX",
"status": {
"id": 124,
"status": "working",
"name": "GFX"
}
},
{
"id": 22,
"name": "GFX",
"status": {
"id": 221,
"status": "working",
"name": "GFX"
}
}
]
},
{
"id": 14,
"name": "UI",
"data": [
{
"id": 14,
"name": "UI",
"status": {
"id": 125,
"status": "working",
"name": "UI"
}
},
//null data if not in first
{}
]
},
{
"id": 23,
"name": "DM",
"data": [
//null data if not in first
{},
{
"id": 23,
"name": "DM",
"status": {
"id": 231,
"status": "done",
"name": "DM"
}
}
]
}
]
}
]
Output should be in array2 structure.
Thanks in advance.
So you just want to have the original data as additional data attribute? This is simple using a forEach() loop in combination with the map() function:
array1.forEach((obj) => {
obj.category = obj.category.map((cat) => {
return {id: cat.id, name: cat.name, data: cat}
});
})
Hope this is what you're looking for :-)

How to access a field in relation in eloquent orm

I wrote this code to get the product information with it's images and category:
->where('category_id', 5)
->with('category', 'Files')->get();
my result is:
{
"id": 2,
"name": "test",
"price": 13000,
"description": "some text ...",
"shop_id": 1,
"rate": 0,
"category_id": 5,
"discount_percent": 20,
"category": {
"id": 5,
"name": "cat1",
"shop_id": 1
},
"files": [
{
"id": 99,
"disk_name": "5ef1af07d6d98778754621.jpg",
"file_name": "13330983_xl.jpg",
"file_size": 69813,
"content_type": "image/jpeg",
"title": null,
"description": null,
"field": "product_gallery",
"sort_order": 99,
"created_at": "2020-06-23 07:28:07",
"updated_at": "2020-06-23 07:28:10",
"path":...... storage/app/uploads/public/5ef/1af/07d/5ef1af07d6d98778754621.jpg",
"extension": "jpg"
}
]
}
now i want to access the path field, how can i do it?
i use this way for access but i don't get result:
products[0].files[0].path
You should use toArray() function to convert data likes this
->where('category_id', 5)
->with('category', 'Files')->get()->toArray();
And then access
products[0]['files'][0]['path']

Compare two array and change styles of ng-repeat items in angular

I have a json like this -
[{
"id": "152",
"name": "Accounting",
"parent_id": "0",
"created_at": "2016-12-20 18:10:57",
"updated_at": "2016-12-20 18:10:57"
}, {
"id": "292",
"name": "Administration",
"parent_id": "0",
"created_at": "2016-12-20 18:37:29",
"updated_at": "2016-12-20 18:37:29"
}, {
"id": "422",
"name": "Banquet",
"parent_id": "0",
"created_at": "2016-12-20 18:43:26",
"updated_at": "2016-12-20 18:43:26"
}, {
"id": "502",
"name": "Engineering & Maintenance",
"parent_id": "0",
"created_at": "2016-12-20 18:47:12",
"updated_at": "2016-12-20 18:47:12"
}, {
"id": "622",
"name": "Food & Beverage Admin",
"parent_id": "0",
"created_at": "2016-12-20 18:51:00",
"updated_at": "2016-12-20 18:51:00"
}, {
"id": "782",
"name": "Food & Beverage Service",
"parent_id": "0",
"created_at": "2016-12-20 18:56:38",
"updated_at": "2016-12-20 18:56:38"
}, {
"id": "982",
"name": "Front Office",
"parent_id": "0",
"created_at": "2016-12-20 19:05:04",
"updated_at": "2016-12-20 19:05:04"
}, {
"id": "1212",
"name": "Housekeeping & Laundry",
"parent_id": "0",
"created_at": "2016-12-20 19:15:48",
"updated_at": "2016-12-20 19:15:48"
}, {
"id": "1352",
"name": "HR",
"parent_id": "0",
"created_at": "2016-12-21 10:12:38",
"updated_at": "2016-12-21 10:12:38"
}, {
"id": "1462",
"name": "IT",
"parent_id": "0",
"created_at": "2016-12-21 10:16:14",
"updated_at": "2016-12-21 10:16:14"
}, {
"id": "1492",
"name": "Kitchen / Food Preparation",
"parent_id": "0",
"created_at": "2016-12-21 10:17:29",
"updated_at": "2016-12-21 10:17:29"
}, {
"id": "1712",
"name": "Purchase",
"parent_id": "0",
"created_at": "2016-12-21 10:26:09",
"updated_at": "2016-12-21 10:26:09"
}]
Which I am iterating in list with ng-repeat.
Now I have another array like
[152,292,422,1712].
Now how do I match the second array with the id of first array and change the style of those matching id's object in the view.
Please suggest.
You can use the ngClass directive.
The code would look something like this, assuming the Json is saved as foodList:
<div ng-repeat="food in foodList">
<div ng-class="{'classNameToWantedStyle': isIDInList(food.id)}">
{{food.name}}
</div>
</div>
and in your controller you would make a corresponding function that returns true if the id is in the list. Here you could use javascripts indextOf method to determine that.
Assuming 'items' is the name of the array, then you have your ng-repeat:
<div ng-repeat="item in items">
You can use ng-switch (or here) to look at each item then separate that out into sections that you can style differently:
<div ng-switch="item.id">
<div ng-switch-when="152" class="152-class"></div>
<div ng-switch-when="292" class="292-class"></div>
<div ng-switch-default class="default-class"></div>
</div>
You get the idea, but take a look at the documentation I linked, they might explain it better.

Resources