How to retrieve nested array data in PHP/Laravel? - php

{`
+"insights": array:1 [▼
0 => {#209 ▼
+"group": "Provision"
+"dataset": array:1 [▼
0 => {#207 ▼
+"group": "Provision"
+"set": array:3 [▼
0 => {#194 ▼
+"name": "Neutral"
+"value": 917
}
1 => {#203 ▶}
2 => {#197 ▶}
]
}
]
}
]
+"errorCode": 0
}`
How to get the name property inside the set array? I've tried multiple way but it kept error return trying to get property non-object.

suppose you provide $response to your blade view
$response = {
+"insights": array:1 [▼
0 => {#209 ▼
+"group": "Provision"
+"dataset": array:1 [▼
0 => {#207 ▼
+"group": "Provision"
+"set": array:3 [▼
0 => {#194 ▼
+"name": "Neutral"
+"value": 917
}
1 => {#203 ▶}
2 => {#197 ▶}
]
}
]
}
]
+"errorCode": 0
}
You have to loop through to response , in your blade view :
#foreach($response->insights as $insight)
#foreach($insight['dataset'] as $dataset)
#foreach($dataset['set'] as $set)
<tr><td>$set['name']</td></tr>
#endforeach
#endforeach
#endforeach

data_get($data, 'insights.0.dataset.0.set.0.name');
end if you have json - convert it into array -> json_decode(string);

You have to simply loop through it and do whatever you want to with that name,
foreach($response->insights as $temp){
foreach($temp->dataset as $var){
foreach($var as $obj){
$name = $obj->name;
}
}
}

Related

Merge a Laravel array of Collections, and add new properties/attributes [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have a collection array of 'Products', as seen from the dump below.
Illuminate\Support\Collection {#918 ▼
#items: array:12 [▼
0 => App\Product {#934 ▶}
1 => App\Product {#943 ▶}
2 => App\Product {#959 ▶}
3 => App\Product {#968 ▶}
4 => App\Product {#984 ▶}
5 => App\Product {#993 ▶}
6 => App\Product {#1009 ▶}
7 => App\Product {#1018 ▶}
8 => App\Product {#1034 ▶}
9 => App\Product {#1043 ▶}
10 => App\Product {#1059 ▶}
11 => App\Product {#1068 ▶}
]
}
This array has ONLY two unique products;
App\Product {#934 ▼
...
+wasRecentlyCreated: false
#attributes: array:10 [▼
"id" => 1
"slug" => "26027686555545"
"details" => App\DispatchStock {#900 ▼
...
#attributes: array:9 [▼
...
"quantity" => 3
"created_at" => "2020-05-04 15:56:07"
]
...
}
]
...
}
and
App\Product {#943 ▼
...
+wasRecentlyCreated: false
#attributes: array:10 [▼
"id" => 2
"slug" => "26027687444410"
"details" => App\DispatchStock {#899 ▼
...
#attributes: array:9 [▼
...
"quantity" => 5
"created_at" => "2020-05-04 15:56:07"
]
...
}
]
...
}
duplicated 6 times each (with varying 'quantity's).
I want to loop through the collection array of 'Products', merge all the duplicates, and return an array of just the unique products.And have something like:
Illuminate\Support\Collection {#918 ▼
#items: array:2 [▼
0 => App\Product {#934 ▶}
1 => App\Product {#943 ▶}
]
}
While appending a new attribute 'combined_available_quantity' (the sum of all the 'quantity's of the Products) to the 'details' property of each of the unique Products.
For example, I want one of the final 'Product's to look like:
App\Product {#943 ▼
...
+wasRecentlyCreated: false
#attributes: array:10 [▼
"id" => 2
"slug" => "26027687444410"
"details" => App\DispatchStock {#899 ▼
...
#attributes: array:9 [▼
...
"quantity" => 5
"created_at" => "2020-05-04 15:56:07"
"combined_available_quantity" => 27
]
...
}
]
...
}
I already started with the code below.
...
$combinedProducts = collect();
foreach ($products as $product) {
$combinedProducts = $combinedProducts->each(function($combinedProduct) use ($combinedProducts, $product) {
if ($combinedProduct->slug == $product->slug) {
$qty = $product->details->quantity + $combinedProduct->details->quantity;
$combinedProduct->details->setAttribute('combined_available_quantity', $qty);
} else {
$product->details->setAttribute('combined_available_quantity', $product->details->quantity);
$combinedProducts->push($product);
}
});
$combinedProducts = $combinedProducts->values();
}
But it's buggy, and doesn't give me required results.
I need a better approach. Thanks.
$collect->groupBy('slug')->map(function($item){
return $item->sum('quantity');
})

Laravel Object of class stdClass could not be converted to string. Still object when using toArray();

I have a table that I want to export via excel. I use the method toArray(); and still I get the result as object. Here is my sample code
$items = \DB::table('users')
->join('finances', 'users.id','=','finances.user_id')
->join('schoolyears', 'users.school_id','=','schoolyears.school_id')
->select('users.name','users.phone','users.section_id', 'users.student_school_id','finances.amount','finances.description','schoolyears.name as syear','finances.date')
->where('finances.date', '=' ,(\DB::raw("(select max(`date`) from finances f where finances.user_id=f.user_id)")))
->where('users.role','=','4' )
->where('users.school_id','=', $sid)
->get()->toArray();
// dd($items);
} else {
return redirect('home')->with('error', 'Invalid access');
}
\Excel::create($this->page_title . 's', function ($excel) use ($items) {
$excel->sheet($this->page_title . 's', function ($sheet) use ($items) {
$sheet->fromArray($items);
});
The result I get when i dd($items)
array:2 [▼
0 => {#558 ▼
+"name": "Annamarie Morar"
+"phone": "(0997) 212-7919"
+"section_id": null
+"student_school_id": "50"
+"amount": "500"
+"description": "New Pays"
+"syear": "SY-2019-2020"
+"date": "2019-11-14"
}
1 => {#561 ▶}
]
What i want is like this so that i can export it as an excel file
array:9 [▼
0 => array:10 [▼
"FirstName" => "Madelynn"
"LastName" => "Stokes"
"Gender" => "female"
"Birthday" => "2013-10-09"
"Address" => "78A/40 Goodwin Meadow, Poblacion, Iloilo City 1333 Nueva Ecija"
"PhoneNo" => "+63 (971) 659-8143"
"Parent" => "Deondre Stokes"
"SchoolID" => "521"
"RFID" => "173"
"Section" => null
]
1 => array:10 [▶]
2 => array:10 [▶]
3 => array:10 [▶]
4 => array:10 [▶]
5 => array:10 [▶]
6 => array:10 [▶]
7 => array:10 [▶]
8 => array:10 [▶]
]
You could convert each object to an array by transforming the Collection then turning the Collection into an array if you had to:
$items = DB::table(...)->.....->get()->transform(function ($item) {
return (array) $item;
})->toArray();
Laravel 6.x Docs - Collections - Methods - transform

Array_merge in laravel

I have data I return them into collection but it does not return as i wish and i need help to fix it.
output
array:11 [▼
0 => Collection {#2762 ▼
#items: array:3 [▼
0 => Product {#2758 ▶}
1 => Product {#2759 ▶}
2 => Product {#2760 ▶}
]
}
1 => Collection {#2792 ▼
#items: []
}
2 => Collection {#2948 ▼
#items: []
}
3 => Collection {#3102 ▼
#items: []
}
4 => Collection {#3216 ▼
#items: []
}
5 => Collection {#2886 ▼
#items: array:10 [▶]
}
6 => Collection {#2920 ▼
#items: array:3 [▶]
}
7 => Collection {#3046 ▼
#items: array:12 [▶]
}
8 => Collection {#3074 ▼
#items: []
}
9 => Collection {#3188 ▼
#items: array:7 [▶]
}
10 => Collection {#3288 ▼
#items: []
}
]
Code
$category = Category::where('slug','=',$catslug)->with('childs', 'parent')->first();
$pp1[] = Product::where('category_id',$category->id)->get();
foreach($category->childs as $first){
$pp2[] = Product::where('category_id',$first->id)->get();
if(count($first->childs)> 0){
foreach($first->childs as $second){
$pp3[] = Product::where('category_id',$second->id)->get();
}
}
}
$products = array_merge($pp1,$pp2,$pp3);
dd($products);
What it should return
It should return all products from all arrays in 1 array only and not categorized by Collection {#2792 ▼ I need to get only collections with items and not the ones that are empty.
Any idea?
update
I've also tried this:
$pp1 = [];
$pp2 = [];
$pp3 = [];
$pp1 = Product::where('category_id',$category->id)->get();
foreach($category->childs as $first){
$pp2 = Product::where('category_id',$first->id)->get();
if(count($first->childs)> 0){
foreach($first->childs as $second){
$pp3 = Product::where('category_id',$second->id)->get();
}
}
}
it returns:
array_merge(): Argument #1 is not an array
You can get all products of the category, of its children and of its grand-children as,
$category = Category::where('slug','=',$catslug)
->with([
'products',
'childs.products',
'childs.childs.products',
'parent'
])
->first()
->toArray();
$products = array_merge([
data_get($category, 'products'),
array_collapse(data_get($category, 'childs.*.products')),
array_collapse(data_get($category, 'childs.*.childs.*.products'))
]);
Fiddle : https://implode.io/ebXrD8

Do you know why it appears "Property [registrationType] does not exist on this collection instance"?

Do you know why the " #if ($nextRegistration->participants->registration_type->contains('certificate_available', 'Y')) [ " shows "Property [registrationType] does not exist on this collection instance"?
I want to show for each registration a link "Get certificate" if the column "certificate_available" of the "registration_types" table has the value "Y".
<ul class="list-group">
#foreach($nextRegistrations as $nextRegistration)
#if(!empty($nextRegistration->conference) || !empty($nextRegistration->conference->start_date))
#if ($nextRegistration->participants->registration_type->contains('certificate_available', 'Y'))
<a href="{{route('conferences.certificateInfo',
[
'regID'=> $nextRegistration->id])}}"
class="btn btn-primary ml-2">Download certificate</a>
#endif
</li>
#endif
#endforeach
</ul>
The participant model has the registration_type():
class Participant extends Model
{
public function registration(){
return $this->belongsTo('App\Registration');
}
public function registration_type(){
return $this->belongsTo('App\RegistrationType');
}
}
To get the $nextRegistrations the code is:
$nextRegistrations = $user->registrations()
->with('participants.registration_type')
->whereHas(
'conference',
function ($query) {
$query->where('end_date', '>', now());
}
)->paginate($pageLimit);
And $nextRegistrations shows like:
LengthAwarePaginator {#336 ▼
#total: 3
#lastPage: 1
#items: Collection {#320 ▼
#items: array:3 [▼
0 => Registration {#308 ▼
...
#relations: array:1 [▼
"participants" => Collection {#327 ▼
#items: array:1 [▼
0 => Participant {#332 ▼
...
#relations: array:1 [▼
"registration_type" => RegistrationType {#337 ▼
#fillable: array:7 [▶]
....
#attributes: array:10 [▼
"id" => 1
"name" => "general"
"description" => "desc general"
"conference_id" => 1
"certificate_id" => 1
"certificate_available" => "Y"
]
...
}
]
...
}
]
}
]
...
}
1 => Registration {#321 ▶}
2 => Registration {#317 ▶}
]
}
....
}
How do you retrieve the data from the database. You may need to use the with method:
$data = Participant::with('registration_type')->get()
or in the view use "registration_type" as a method, not as a property:
$nextRegistration->participants->registration_type()
You can find more about the belongs to relationship here: https://laravel.com/docs/5.6/eloquent-relationships#one-to-many-inverse

Laravel - How to collect multiple array to single one

I've created a collection like this :
Collection {#651 ▼
#items: array:3 [▼
0 => array:3 [▼
"orderId" => "402457"
"orderCreated" => DateTime {#656 ▶}
"foods" => array:2 [▶]
]
1 => array:3 [▼
"orderId" => "402457"
"orderCreated" => DateTime {#661 ▶}
"foods" => array:2 [▶]
]
2 => array:3 [▼
"orderId" => "402457"
"orderCreated" => DateTime {#665 ▶}
"foods" => array:2 [▶]
]
]
}
I demand to achieve collection like this (with Laravel collection):
Collection {#651 ▼
#items: array:3 [▼
0 => array:3 [▼
"orderId" => "402457"
"orderCreated" => DateTime {#656 ▶}
"foods" => array:6 [▶]
]
]
}
Because orderId and orderCreated are all the same in arrays. I need to make single array that collect orderId and orderCreated with all foods.
Any suggestion?
You can take the data from the first one and just combine all of the food items. For instance like this:
$new = collect([
'orderId' => $old->first()->orderId,
'orderCreated' => $old->first()->orderCreated,
'foods' => $old->pluck('foods')->flatten(1),
]);
The exact implementation will depend on how you built your initial collection.

Categories