Laravel collections iteration with foreach loop - php

its a simple query in a controller using Order model:
$orders = Order::where('user_id', auth()->user()->id)
->orderBy('created_at', 'desc')
->get();
return dd($orders);
dd gives following results: (which is correct)
Collection {#269 ▼
#items: array:2 [▼
0 => Order {#270 ▼
#dates: array:1 [▶]
#fillable: array:6 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:9 [▶]
#original: array:9 [▶]
#changes: []
#casts: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
#forceDeleting: false
}
1 => Order {#271 ▼
#dates: array:1 [▶]
#fillable: array:6 [▶]
#connection: "mysql"
#table: null
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:9 [▶]
#original: array:9 [▶]
#changes: []
#casts: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
#forceDeleting: false
}
]
}
but when i iterate through the $orders collection foreach loop, only the first array is is shown, the second array is not accessible... whats wrong with foreach loop... ?
$temp='';
foreach($orders as $order){
$temp.= $order->product; // accessing the belongTo method
}
dd($temp);
here is the output (only one array is shown):
"{"id":13,"created_at":"2018-06-06 15:28:21","updated_at":"2018-06-06 18:36:28","type":0,"title":"product 3","description":"this is product no 3 with 5 images","images":"night-product-watch-dramatic-84475_1528310188.jpeg,night-product-watch-dramatic-84475_1528310188.jpeg","alive":1,"user_id":1,"deleted_at":null} ◀"

If you are building an array of products across all orders you cannot use string concatenation. Use an array and push items onto it.
$products = [];
foreach ($orders as $order) {
if ($order->product) {
$products[] = $order->product;
}
}
dd($products); // will be an array of all other products.

Try this:
$temp= [];
foreach($orders->all() as $order){
$temp[] = $order->product;
}
And you may edit your query
$orders = Order::where('user_id', auth()->user()->id)
->with('products')
->orderBy('created_at', 'desc')
->get();

Related

Paginator data don't show well in livewire "public property [posts] must be of type: [numeric, string, array, null, or boolean]"

I like to use livewire instead of controller
public function index()
{
return view('advert.index', [
'posts' => Advert::latest()->filter(
request(['search', 'category', 'author'])
)->paginate(18)->withQueryString()
]);
}
in livewire <livewire:advert.home :querys="request(['search', 'category', 'author'])">
public function mount($querys)
{
$this->querys = $querys;
}
public function render()
{
$this->posts = Advert::latest()->filter([$this->querys])->paginate($this->perPage)->withQueryString();
}
but nothing work
it is mostly say
Livewire component's [advert.home] public property [posts] must be of
type: [numeric, string, array, null, or boolean]. Only protected or
private properties can be set as other types because JavaScript
doesn't need to access them.
I am lost i use this but it don't work well and show error above. and look same data passed to livewire component.
and there is no difference between livewire $this->posts and 'posts' from controller i can't figure about that.
like
'posts' dd($posts) from controller
Illuminate\Pagination\LengthAwarePaginator {#1412 ▼
#total: 2
#lastPage: 1
#items: Illuminate\Database\Eloquent\Collection {#1402 ▼
#items: array:2 [▼
0 => App\Models\Advert {#1409 ▼
#with: array:3 [▶]
#fillable: array:8 [▶]
#connection: "mysql"
#table: "adverts"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:12 [▶]
#original: array:12 [▶]
#changes: []
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:3 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => App\Models\Advert {#1410 ▼
#with: array:3 [▶]
#fillable: array:8 [▶]
#connection: "mysql"
#table: "adverts"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:12 [▶]
#original: array:12 [▶]
#changes: []
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:3 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
#perPage: 18
#currentPage: 1
#path: "https://awento.ddns.net/search"
#query: []
#fragment: null
#pageName: "page"
+onEachSide: 3
#options: array:2 [▶]
}
and livewire $this->posts
ddd($posts)
Illuminate\Pagination\LengthAwarePaginator {#1470 ▼
#total: 2
#lastPage: 1
#items: Illuminate\Database\Eloquent\Collection {#1458 ▼
#items: array:2 [▼
0 => App\Models\Advert {#1465 ▼
#with: array:3 [▶]
#fillable: array:8 [▶]
#connection: "mysql"
#table: "adverts"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:12 [▶]
#original: array:12 [▶]
#changes: []
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:3 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
1 => App\Models\Advert {#1467 ▼
#with: array:3 [▶]
#fillable: array:8 [▶]
#connection: "mysql"
#table: "adverts"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#attributes: array:12 [▶]
#original: array:12 [▶]
#changes: []
#casts: []
#classCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:3 [▶]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
}
]
}
#perPage: 15
#currentPage: 1
#path: "https://awento.ddns.net"
#query: []
#fragment: null
#pageName: "page"
+onEachSide: 3
#options: array:2 [▶]
}
After some trail and error i realise the issue is with whole data if we arrange in some form of data that there will be no issue. So Now i create a array for transfer data with some foreach. If there is another better way please let me know.
$postss = Advert::latest()->filter($this->querys)->paginate($this->perPage)->withQueryString();
$posts = array();
foreach($postss as $post)
{
array_push($posts, $post);
}
$this->posts = $posts;
It seem paginate don't work in livewire using limit now.

Laravel trying to query relatinship model hasMany

I have the following tables in my application:
projects
projects_plot_types
Projects can have many plot types. I have the following relationship setup in the projects model.
/**
* The plot types that belong to the project.
*
* #return Object
*/
public function plotTypes()
{
return $this->hasMany('App\Models\Project\ProjectsPlotTypes');
}
I want to be able to get the plot type by querying it's name on the project model.
I have tried this, but it does not work:
$project->with('plotTypes')->whereHas('plotTypes', function ($query) use ($row) {
$query->where('name', $row->plot_name);
})->first()->plotTypes->first()->id;
Can someone point me in the right direction?
The output of $result as per below comment is:
Project {#705 ▼
#table: "projects"
#fillable: array:7 [▶]
+timestamps: true
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
#attributes: array:10 [▶]
#original: array:10 [▶]
#relations: array:1 [▼
"plotTypes" => Collection {#769 ▼
#items: array:1 [▼
0 => ProjectsPlotTypes {#774 ▼
#table: "projects_plot_types"
#fillable: array:2 [▶]
+timestamps: false
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
#attributes: array:4 [▼
"id" => "2"
"project_id" => "1"
"name" => "TYPE 3 - VENTILATION"
"budget" => "245.69"
]
#original: array:4 [▶]
#relations: []
#hidden: []
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
]
}
]
#hidden: []
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
You may also use join query like below
$result = Illuminate\Support\Facades\DB::table('projects')
->join('projects_plot_types', 'projects_plot_types.id', '=', 'projects.project_plot_id')
->where('projects_plot_types.name', '=', $row->plot_name)
->first();
print_r($result);
Maybe this is what you are looking for:
$result = $project->with(['plotTypes' => function($query) use ($row) {
return $query->where('name', $row->plot_name)->first();
}])->first();
dd($result); // print the result and die
UPDATE 1
Fetch the first item from the collection that has BelongsTo relationship:
$plotTypeResult = $result->plotTypes[0]->id;

Array of objects , that won't loop in a foreach in laravel

I'm not sure this is really a laravel question but, when I dd(die and dump) this dd($user->friends()); I get the following. I did notice that it is a collection. I'm not sure if that means something different or not. But it still should be an array of items I believe. With the first user at the [0] mark and next [1], etc...
Collection {#184 ▼
#items: array:2 [▼
0 => User {#189 ▼
#table: "users"
#fillable: array:7 [▶]
#hidden: array:3 [▶]
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:11 [▶]
#original: array:13 [▶]
#relations: array:1 [▶]
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
1 => User {#190 ▼
#table: "users"
#fillable: array:7 [▶]
#hidden: array:3 [▶]
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:11 [▶]
#original: array:13 [▶]
#relations: array:1 [▶]
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
]
}
So then when I try to do something like :
foreach($user->friends() as $friend) {
dd($friend);
}
This is what I get after doing that:
User {#189 ▼
#table: "users"
#fillable: array:7 [▶]
#hidden: array:3 [▶]
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:11 [▶]
#original: array:13 [▶]
#relations: array:1 [▶]
#visible: []
#appends: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
I want it to loop through all the users not just the first one. Is there a reason it is doing this. Am I doing the foreach wrong or does it have something to do with the collection?
When you do your foreach, you're only seeing one entry because of the dd(). Remember, it is "dump and die", so on the very first iteration, you're dumping the record and then dying.
Try this out:
foreach($user->friends() as $friend) {
print_r($friend);
}
If you just want to treat it as an array, use toArray on the collection first. Eg:
$friends = $user->friends()->toArray();
foreach($friends as $friend){
...some stuff...
}
Otherwise, use the features of the laravel collection as per the docs here:
http://laravel.com/docs/5.2/collections

How to access single value property of a collection in laravel 5

I have a variable passed though my controller in my view :
name is $others
and when I do a foreach and print it like
#foreach($others as $other)
{{ $other }}
#endforeach
the output is :
[{"employeeID":"9125123981003","email":"admin#gaincafe.com","fullName":"Pranshu Jain"}] [{"employeeID":"45755757577","email":"yoyo#pranshu.com","fullName":"Pranshu Jain"}]
What I want is to access single properties from these ? Are they collections ?
I tried like this
#foreach($others as $other)
{{ $other->email }}
#endforeach
Here is how I get this $others filled :
public function show($id)
{
$this->data['leave_application'] = Attendance::find($id);
$date_applied_on = $this->data['leave_application']->date;
$emp_id = $this->data['leave_application']->employeeID;
$other_on_leave = Attendance::where('date', '=', $date_applied_on)->get();
$employees_on_leave = [];
foreach($other_on_leave as $others) {
if($emp_id != $others->employeeID) {
$emptyarray = Employee::where('employeeID', '=', $others->employeeID)->get(array('employeeID','email','fullName'));
$employees_on_leave[] = $emptyarray;
}
}
$this->data['others'] = $employees_on_leave;
return view('admin.leave_applications.show', $this->data);
}
But it does not work. Kindly help and guide a little bit. I am familiar with array and objects. I used to do well with them. but this seems little complicated.
If i do dd($others) then i get
array:2 [▼
0 => Collection {#344 ▼
#items: array:1 [▼
0 => Employee {#345 ▼
#guarded: array:1 [▼
0 => "id"
]
#hidden: array:1 [▼
0 => "password"
]
#connection: null
#table: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:3 [▶]
#original: array:3 [▶]
#relations: []
#visible: []
#appends: []
#fillable: []
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
]
}
1 => Collection {#346 ▼
#items: array:1 [▼
0 => Employee {#347 ▼
#guarded: array:1 [▶]
#hidden: array:1 [▶]
#connection: null
#table: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:3 [▶]
#original: array:3 [▶]
#relations: []
#visible: []
#appends: []
#fillable: []
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
+wasRecentlyCreated: false
}
]
}
]
Try first() instead of get() here:
$emptyarray = Employee::where('employeeID', '=', $others->employeeID)->first(array('employeeID','email','fullName'));
If you still wanted to use get(), then do as follow:
foreach($other_on_leave as $others) {
if($emp_id != $others->employeeID) {
$emptyarray = Employee::where('employeeID', '=', $others->employeeID)->get(array('employeeID','email','fullName'));
foreach($emptyarray as $arr){
$employees_on_leave[] = $arr;
}
}
}
And change this line also, so the view can understand what to loop through:
return view('admin.leave_applications.show', ['others' => $this->data['others', 'leave_application' => $this->data['leave_application']]);
Let me know if it worked.

laravel 5 edit elequent not working

I am trying to edit my data field with following elequent but its not picking up the data, any help appreciated.
following is the data controller i am using:
public function edit($name)
{
$category = category::where('name', $name)->get()->all();
dd($category);
return view('/editcategory')->with('category', $category);
}
while checking the output it not picking up the data from the db
output:
array:1 [▼
0 => category {#190 ▼
#table: "category"
#connection: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:5 [▶]
#original: array:5 [▶]
#relations: []
#hidden: []
#visible: []
#appends: []
#fillable: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
}
]
Don't use both get() and all() in the same time.
It should be:
public function edit($name)
{
$category = category::where('name', $name)->all();
[...]
}

Categories