Laravel acces variable from inside $collection->each() loop [duplicate] - php

This question already has answers here:
Reference: What is variable scope, which variables are accessible from where and what are "undefined variable" errors?
(3 answers)
Closed 1 year ago.
I want build a new collection from an existing collection using an each() loop:
$spot = Spot::where('slug', $slug)->first()->load('features.group');
$test = collect();
$spot->features->each(function ($item, $key) {
$current = collect([
$item->group->name => $item->name,
]);
$test->mergeRecursive($current);
});
dd($test);
I am getting the error Undefined variable $test from the code inside the loop. How can I access the $test collection from inside the loop?
Thanks!

You can pass data inside the closure by use(). Try this:
$spot = Spot::where('slug', $slug)->first()->load('features.group');
$test = collect();
$spot->features->each(function ($item, $key) use(&$test) {
$current = collect([
$item->group->name => $item->name,
]);
$test->mergeRecursive($current);
});
dd($test);

Related

How to display data passed to Blade view [duplicate]

This question already has answers here:
How to pass data to view in Laravel?
(15 answers)
Closed 1 year ago.
How to display variable ['attributes'] & ['products'] separately in blade
$data = [];
$data ['attributes'] = Attribute::active()->whereNull('option_id')->get();
$data ['products'] = Product::orderBy('id', 'DESC')->get();
return view('dashboard.productOption.edit', compact('prOption','data'));
You call them as you would any other associative array element:
#foreach ($data['attributes'] as $attribute)
<p>{{ $attribute }}</p>
#endforeach
The same applies for accessing products.

Laravel query builder combine pluck() with keyBy() [duplicate]

This question already has answers here:
Laravel Eloquent Pluck without losing the key
(7 answers)
Closed 1 year ago.
I would like Laravel query-builder to return an array of key => value.
For example, for users table which has columns username, email return something like:
Array
(
[email1] => username1
[email2] => username2
)
Now, I can achieve each one of the with either pluck('username') or with keyBy('email').
I can use php array functions to manipulate result returned by keyBy in order to achieve what I want:
$tmpRes = DB::table('users')
->select(['username', 'email'])
->get()->keyBy('email')->toArray();
$res = array_map(function ($el) {
return $el->username;
}, $tmpRes);
I wonder whether there is a direct way to do so.
Pluck actually allows a second parameter as a key
public static function pluck($column, $key = null)
So all you have to do is pass that in
$tmpRes = DB::table('users')
->pluck('username', 'email')
->toArray();

Laravel collection for loops and mappings

I am trying to refactor my code, and remove a for loop.
$result = [];
foreach ($data as $language) {
$result[$language->{$key}] = $language->{$column};
}
This became:
$result = $data->map(function($language) use ($key, $column){
return [$language->{$key} => $language->{$column}];
});
But now instead of:
[
"key":"value",
"key":"value"
]
I am getting
[
{
"key":"value"
},
{
"key":"value"
}
]
Why doesn't it map like an array?
Please refer this URL
For Example:
$emailLookup = $employees->reduce(function ($emailLookup, $employee) {
$emailLookup[$employee['email']] = $employee['name'];
return $emailLookup;
}, []);
Gives you result like:
const emailLookup = {
'john#example.com': 'John',
'jane#example.com': 'Jane',
'dave#example.com': 'Dave',
};
In your case do like:
$result = $data->reduce(function($language, $a){
$language[$a['any_you_want']] = $a['any_you_want'];
return $language;
}, []);
Hope this helps you!
You probably needed to mapWithKeys:
$result = $data->mapWithKeys(function($language) use ($key, $column){
return [$language->{$key} => $language->{$column}];
});
The method has been available since Laravel 5.3
According to the docs:
The mapWithKeys method iterates through the collection and passes each value to the given callback. The callback should return an associative array containing a single key / value pair:
For your simple use case, pluck() is the method you're looking for. It will build a new collection using one column of an existing array. You can also pass in a second field that will be used to key the new collection.
So, in your case, the data column you're selecting is $column, and the column to use as the key for the new collection is $key. Your code would be:
$result = $data->pluck($column, $key);
This says "give me a collection of all of the $column data, and key it by the $key data".
If you want the plain array instead of the collection, just call all() on the result:
$result = $data->pluck($column, $key)->all();
If you need to "pluck" more than one column of data, you will need to use the mapWithKeys() method already mentioned.
Here in loop you need to use as key value pair
$result = [];
foreach ($data as $key => $language) {
$result[$key] = $language;
}

push data in to a multidimensional array in laravel php

I want to create a multidimensional array to save the data according the date and a category as follow. Then i need to display this data in my blade view?what can i do to achieve this.
'2012-05-05' => array(
'suspension' => 52,
'transmission' => '58'
),
'2012-05-05' => array(
'suspension' => 44,
'transmission' => 21
I have done the following in my controller i want a $reportData variable to load the data.
public function loadReports(Request $request)
{
$data = ['2012-05-05','2012-05-06'];
$salesItems = array();
$orderItems = OrderItem::with('spare', 'order')->get();
foreach ($orderItems as $key => $orderItem) {
if ($orderItem->spare->retailer_id == Auth::user()->id) {
array_push($salesItems, $orderItem);
}
}
$categories = App\Categories::all();
foreach ($data as $date) {
foreach ($categories as $category) {
$categoryValue = 0;
foreach ($salesItems as $salesItem) {
if ($date == $salesItem->order->orderDate) {
$categoryValue += $categoryValue + $salesItem->subTotal;
}
}
//error appears as illegal offset type
$reportData[$date][$category]=$categoryValue;
}
}
return View::make('Retailer/reports')->with('categories', $categories)->with('reportData', $reportData);
}
I haven't tested it but looking at your code it seems that you're passing an object as array index key as 2nd level array index:
$reportData[$date][$category] = $categoryValue;
^^^^^^^^^ this is an object
Dump your $category in the foreach loop & check if that is the case: dd($category)
If you're using Eloquent & your Categories Model has a name property, you'll probably want to take each category name as index value:
$reportData[$date][$category->name] = $categoryValue;
The error is occurring due to the fact that you are trying to use an Object as the array's index.
As per the laravel documentation (https://laravel.com/api/4.2/Illuminate/Database/Eloquent/Model.html#method_all) the all method you called here '$categories = App\Category::all();' would have returned an Eloquent Collection.
So when you iterated over the $categories array and referenced $category, you were referencing an object. In PHP an array can only be indexed by either an integer or a string. So you need to change the line of code where the error is to this
$reportData[$date][$category->someVar] = $categoryValue;
Where someVar is the name of a variable on the Eloquent model Category that references its name, such as 'suspension' etc.
While it doesn't answer your question you could use the Eloquent engine to make your life easier:
$orderItems = OrderItem::with('spare', 'order')->get();
foreach ($orderItems as $key => $orderItem) {
if ($orderItem->spare->retailer_id == Auth::user()->id) {
array_push($salesItems, $orderItem);
}
}
can be simplified (and made more efficient) with:
// Store the uid to save the call.
$user_id = Auth::user()->id;
// Apply the condition to the Eloquent query.
$orderItems = OrderItem::with(['spare' => function($query) use ($user_id) {
return $query->where('retailer_id', '=', $user_id);
}, 'order'])->get();
The other answers are correct, but you probably also want to initialise the $reportData array as before you start working with it.

CakePhp - how to access variables inside find->innerJoinWith? [duplicate]

This question already has answers here:
PHP variables in anonymous functions
(2 answers)
Closed 7 years ago.
I am trying to query for users that are assigned to a certain project in CakePHP. How could I basically achieve this:
$projectId = //Project ID query result.
$users = $this->Tickets->Users
->find('list', ['limit' => 200])
->innerJoinWith(
'ProjectsUsers', function($q){
return $q->where(['ProjectsUsers.project_id' => $projectId]);
}
);
This code works when not using variables (eg. replacing $projectId with 8) but when I try to use variables I get: Undefined variable: projectId
How can I pass variables into innerJoinWith?
If you mean how to inherit a variable from the parent scope, you'd do it like this.
$users = $this->Tickets->Users
->find('list', ['limit' => 200])
->innerJoinWith(
'ProjectsUsers', function($q) use($variableToPass) {
return $q->where(['ProjectsUsers.project_id' => $variableToPass]);
}
);

Categories