Passing variables,arrays and objects to view with compact - laravel

I have a method in laravel that aims to pass data to views. I have data in variables, arrays and objects.
This is the method
public function view($id){
$id = request()->segment(2);
$items = Role::all(['name', 'display_name']);
return view('text.ServicesEditUser',compact('items',$items));
}
I also have this code
$uid = Auth::id();
$settings = Settings::where('user_id','=',Auth::id())->first();
return view('text.settings',compact('settings'));
that i want to incorporate to the code above. Once i pass the settings to the view, i can access data like $settings->language for instance. I also want to pass a variable which is
$title = 'degrees of tilt';
to the first code snippet's compact method.
This is the method now with all the data i want to pass to the view
public function view($id){
$id = request()->segment(2);
$title = 'Tilt in degrees';
$settings = Settings::where('user_id','=',Auth::id())->first();
$users = User::where('id','=',$id)->get();
$items = Role::all(['name', 'display_name']);
return view('text.ServicesEditUser',compact('items',$items));
}
How do i pass $settings ,$title,$users , $items to the view and how do i access each in view?

When returning a view you can pass multiple variables like this.
return view('text.ServicesEditUser')
->with(compact('items',$items))
->with('variable2', $variable2);
See here the documentation about this - Laravel Views.

In controller:
$variable = "Var";
$array = ["first" => "a", "second" => "b"];
$object = (object) $array;
return view('view',compact(['variable', 'array', 'object']));
In view:
{{$variable}}
{{$array['first']}}
{{$object->first}}

compact() doesn't need dollar at start.
You can just add your code to view by:
$title = 'My title';
$settings = ['my', 'settings',];
return view('text.settings', compact('title', 'settings'));
Anyway you can pass your variables by array:
$settings = ['my', 'settings',];
return view('text.settings', [
'title' => 'Title',
'settings' => $settings,
]);
The last option is with() method:
return view('text.settings')
->with('settings', $settings)
->with('title', 'My title');
Get access to variables in the view by {{ $title }} and
#foreach ($settings as $sett)
{{ $sett }}
#endforeach

This did also work
public function view($id){
$id = request()->segment(2);
$title = 'Degrees of tilt';
$settings = Settings::where('user_id','=',Auth::id())->first();
$users = User::where('id','=',$id)->get();
$items = Role::all(['name', 'display_name']);
return view('text.ServicesEditUser', compact('title', 'settings','users','items'));
}
in the blade view
<p>{{$title}}</p>
{{$settings->language}}
#foreach($items as $item)
<option value="{{$item->name}}">{{$item->display_name}}</option>
#endforeach
#foreach($users as $user)
<option value="{{$user->id}}">{{$user->email}}</option>
#endforeach
In settings
#if($settings)
$settings->language
#endif

Related

ERROR - Trying to get property of non-object - in laravel

I am getting the problem when i fetch categorey name from categorey table ..
code here ..
Thanks.
public function viewProducts(){
$products = Product::get();
$products = json_decode(json_encode($products));
foreach($products as $key => $val){
$category_name = Category::where(['id'=>$val->category_id])->first();
$products[$key]->category_name= $category_name->name;
}
echo "<pre>";print_r($products);die;
return view('admin.products.view_products')->with(compact('products'));
}
ErrorException (E_NOTICE)
Trying to get property of non-objectenter image description here
The error is straight forward. You haven't gotten any objects of $category_name variable and you're trying to access to the value of the name property. Which is not defined because there's no object.
Add a simple condition to fix it like this
public function viewProducts(){
$products = Product::get();
$products = json_decode(json_encode($products));
foreach($products as $key => $val){
$category_name = Category::where(['id'=>$val->category_id])->first();
if($category_name != null){
$products[$key]->category_name= $category_name->name;
}
}
echo "<pre>";print_r($products);die;
return view('admin.products.view_products')->with(compact('products'));
}
To send data to your blade:
# Controller:
$data['category_name'] = $category_name;
$data['products'] = $products;
->withKeyName($data);
# Blade:
{{ $KeyName['category_name'] }}
{{ $KeyName['products'] }}

Trying to get property 'name' of non-object

In code Controller recieving data from model but failed to show in blade view file.
This is blade view code.
#for($id = 0;$id < 59;$id++)
#foreach($data[$id] as $data)
{{$data->name}}
#endforeach
#endfor
Here is the controller
public function cart(){
$data = array();
$data['flashSale'] = Product::flashSale();
$cartProdId = Session::get('prodId');
for ($id = 0;$id<sizeof($cartProdId);$id++){
$data[$id] = Product::getCartProduct($cartProdId[$id]);
}
return view('user.cart')->with('data',$data);
}
you are using two loops unnecessarily..you can achieve this by using only one loop if it is for or foreach loop...
You can do it by single foreach loop. It will save execution/loading time.
#foreach($data as $key => $value)
{{$value->name}}
#endforeach
Do smart work!! .

Laravel 5.7 - Pivot table attach()

I cannot get attach() to work in my setup.
Each User can have many Orders which can have many Products.
User.php
public function orders()
{
return $this->hasMany(Order::class);
}
Order.php
public function users()
{
return $this->belongsTo(User::class);
}
public function products()
{
return $this->belongsToMany(Product::class)
->withTimestamps()
->withPivot('qty');
}
Product.php
public function orders()
{
return $this->belongsToMany(Order::class)
->withTimestamps()
->withPivot('qty');
}
I have a create.blade.php which is meant to show all available products and the quantity for each can be chosen, this is to be saved on the pivot table.
create.blade.php
{{ Form::open(array('url' => '/orders/store')) }}
#foreach ($products as $product)
<div>
<span class="mealname">{{ $product->name }}</span>
<hr>
<p>{{ $product->description }}</p>
</div>
<div class="qty">
{{ Form::text( 'qty', 0, [ 'type' => 'tel' ]) }}
</div>
#endforeach
{{ Form::select('delivery_day', ['M' => 'Monday', 'W' => 'Wednesday'],
null, ['placeholder' => 'Delivery Day'])
}}
{{ Form::submit('Place Order') }}
{{ Form::close() }}
When I submit the request only the fields to the Order table are saved,
public function store(Request $request)
{
// Validate
$request->validate([
'qty'=> 'integer',
]);
# Create New Order
$order = new Order;
$id = Auth::user()->id;
$order->user_id = $id;
// passed in parameters of form (not qty)
auth()->user()->orders()->save($order); // save order
# Pivot attach()
HERE I AM LOST
return redirect('complete')->with('success', 'Order has been created');
}
I believe it is the fact that I am trying to pass multiple products in one form, (which I believe i should be able to just pass as an arry while I use attach().
I have tried various solutions and I am still unable to ever get the pivot table to populate.
My last attempt was to pass the product_id through a hidden field and then running this.
$attach_data = [];
for ($i = 0; $i < count($product_ids); $i++);
$attach_data[$product_ids[$i]] = ['qty' => $qtys[$i]];
$order->product_ids()->attach($attach_data);
However, this did not work.
According to the docs (https://laravel.com/docs/5.7/eloquent-relationships#updating-many-to-many-relationships) this is one way to attach multiple items:
$user->roles()->attach([
1 => ['expires' => $expires],
2 => ['expires' => $expires]
]);
So you have to modify this:
# Create New Order
$order = new Order;
$id = Auth::user()->id;
$order->user_id = $id;
$order->save();
// change this for your array of ids
$products_to_sync_ids = [1,3,23];
$sync_data = [];
$qty = 1; <----- I dont know if you are inserting them with the same qty
for($i = 0; $i < count($products_to_sync_ids); $i++))
$sync_data[$products_to_sync_ids[$i]] = ['qty' => $qty];
$order->products()->sync($sync_data);
Try and check if the products are inserting correctly on the pivot table and then modify the code to insert every code with his quantity.

Laravel change pagination data

My Laravel pagination output is like laravel pagination used to be, but I need to change the data array for each object.
My output is:
As you can see, the data object has 2 items, which I need to change.
My code is:
$items = $this->items()
->where('position', '=', null)
->paginate(15);
Which returns the user items with pivot table, but I don't like the way the pivot table is shown in the JSON, so I decided to change the items and organize each item with the pivot before the item.
For this purpose, I tried to use foreach
foreach ($items->data as $item)
{
}
which giving my an error, for a reason I don't know:
Undefined property: Illuminate\Pagination\LengthAwarePaginator::$data"
status_code: 500
Any help?
The paginator's items is a collection. You can grab it and transform the data like so:
$paginator = $this->items()->where('position', '=', null)->paginate(15);
$paginator->getCollection()->transform(function ($value) {
// Your code here
return $value;
});
If you are familiar with tap helper here is the snippet that does exact same.
$paginator = tap($this->items()->where('position', '=', null)->paginate(15),function($paginatedInstance){
return $paginatedInstance->getCollection()->transform(function ($value) {
return $value;
});
});
We can't chain method getCollection to paginator instance because AbstractPaginator will return paginator's underlying collection. so the paginator instance will be transformed to Collection. So fix that we can use tap helper.
If you'd like to keep items paginated:
$itemsPaginated = $this->items()
->paginate(15);
$itemsTransformed = $itemsPaginated
->getCollection()
->map(function($item) {
return [
'id' => $item->id,
];
})->toArray();
$itemsTransformedAndPaginated = new \Illuminate\Pagination\LengthAwarePaginator(
$itemsTransformed,
$itemsPaginated->total(),
$itemsPaginated->perPage(),
$itemsPaginated->currentPage(), [
'path' => \Request::url(),
'query' => [
'page' => $itemsPaginated->currentPage()
]
]
);
There is a setCollection method for such purpose.
$items = Model::paginate(10);
$updatedItems = $items->getCollection();
// data manipulation
// ...
$items->setCollection($updateItems);
From the source code of /Illuminate/Pagination/AbstractPaginator.php
/**
* Set the paginator's underlying collection.
*
* #param \Illuminate\Support\Collection $collection
* #return $this
*/
public function setCollection(Collection $collection)
{
$this->items = $collection;
return $this;
}
Source
I could make shorter way. This returns edited $array instead of simple $paginated. This example modify file names.
This doc was useful for me.
$paginated=$query->paginate(12);
$array=$paginated->toArray();
foreach ($array['data'] as $r=>$record) {
$array['data'][$r]->gif=$array['data'][$r]->gif.".gif";
}
return $array;
Sample Example :
$franchiseData=[ 'id'=>1 ,'name'=>'PAnkaj'];
$models = $bookingsQuery->paginate(10);
$models->setCollection(collect($franchiseData));
return $models;
Note that $models->setCollection(collect($franchiseData)); you have to use collect() else you will get error.
getCollection
is one way to get the items. Another way is to use this
For ex- Assuming, user doesn't have name param and only have first_name and last_name
$userPaginatedData = User::paginate(15);
$users = $userPaginatedData->items();
foreach($users as $user) {
$user->name = $user->first_name . ' ' . $user->last_name;
}
return $userPaginatedData;
Now in the data key, you would see that each user has name param with it.
Laravel 8.9.0 has added the through method to AbstractPaginator.
It transforms each item in the slice of items using a callback, and keeps the items paginated.
$paginator = $this->items()->where('position', '=', null)->paginate(15);
$paginator->through(function ($value) {
// Your code here
return $value;
});
The source code:
/**
* Transform each item in the slice of items using a callback.
*
* #param callable $callback
* #return $this
*/
public function through(callable $callback)
{
$this->items->transform($callback);
return $this;
}
-Laravel 5.4
// example update column "photo"
// from "/path/to/photo.png"
// to "abc.com/path/to/photo.png"
foreach ($items as $item)
{
$path = $item->photo;
// Remove
$item->offsetUnset("photo");
// Set
$item->offsetSet("photo", url($path));
}
Laravel AbstractPaginator has methods setCollection() and getCollection()
<?php
$itemsPaginated = $this->items()->paginate(15);
$itemsPaginated->setCollection(
$itemsPaginated->getCollection()->transform(function ($item) {
// Your code here
return $item;
})
)
This is your paginated items...
$items = $this->items()
->where('position', '=', null)
->paginate(15);
I am using Laravel 8, can simply use each
$items->each(function ($item) {
// your code here
$item->custom_data = calcSomeData(); // sample
});
It does the same as this...
$items->getCollection()->transform(function ($item) {
// your code here
$item->custom_data = calcSomeData(); // sample
});
<?php
$itemsPaginated = $this->items()->paginate(15);
$itemsPaginated = json_encode($itemsPaginated);
foreach ($itemsPaginated->data as $key => $item) {
$results->data[$key]; //Modify
}
$itemsPaginated = json_encode($results);
you have to use below code in your blade
{!! $items->render() !!}
Ignore the pagination in laravel and hit the normal data
foreach ($items as $item)
{
}

Laravel: Error in Passing a multidimensional array from controller to view in Laravel

Route File:-
Route::get('/',function()
{
$menuitem = Menuitem::all();
return VIEW::make('index',$menuitem);
});
index.blade.php:-
#foreach($menuitem as $item)
{{$item['item_link']}}
#endforeach
I am getting an error Undefined variable $menuitem in index.blade.php.
Try
Route::get('/',function()
{
$menuitem = Menuitem::all();
return View::make('index')->with('menuItem', $menuItem);
}
View::make accepts an array for the second parameter.
public View make(string $view, array $data = array(), array $mergeData = array())
So it should be:
Route::get('/',function()
{
$menuitem = Menuitem::all();
$data = array(
'menuitemKey' => $menuitem
);
return View::make('index', $data);
}
Then you can access it like:
#foreach($menuitemKey as $item)
{{$item['item_link']}}
#endforeach
This worked for me.
'Route('/',function(){
$myarray = Menuitem::all();
return View::make('myview')->with('data',$myarray);
})'
myview.blade.php
'#for($i=0;$i<sizeof($data),$i++)
{{$data[$i]['item']}}
#endfor'

Resources