Object getting converted to array? - laravel

I'm trying to update a notification's data (for displaying it in a view):
$notifications = $user->notifications()->paginate(15);
foreach ($notifications as $notification)
{
$post = Post::where('id', $notification->data['post_id'])
->first();
$notification->data = $post;
}
But when I do this in my view:
#foreach ($notifications as $notification)
{{ gettype($notification->data) }}
#endforeach
It shows that the data is an array. Why does it convert the Post model object to an array and how can I stop this from happening?

Your $notification object is an instance of Illuminate\Notifications\DatabaseNotification. This is an Eloquent Model that has the following $casts property defined:
protected $casts = [
'data' => 'array',
'read_at' => 'datetime',
];
Because of this, when you access $notification->data, it will automatically be cast to an array.
To resolve your issue, and to reduce the number of database queries, you should just build a separate lookup collection of posts, and pass that into the view.
First, build an array of all the Post ids. Then, run one query to get all the Post|s for those ids. After that, re-key the resulting Collection of Post|s by the id for easy lookup later in the view. Make sure to pass your Collection of Post|s to the view.
$notifications = $user->notifications()->paginate(15);
$postIds = [];
foreach ($notifications as $notification) {
$postIds[] = $notification->data['post_id'];
}
$posts = Post::whereIn('id', array_unique($postIds))->get()->keyBy('id');
Then, in your view:
#foreach ($notifications as $notification)
{{ $posts->get($notification->data['post_id']) }}
#endforeach

You were not updating in $notifications that's why you are seeing old array not the new object you wanted to save.
foreach ($notifications as $key => $notification)
{
$post = Post::where('id', $notification->data['post_id'])->first();
$notifications[$key]->data = $post;
}

Related

Laravel Collection paginate does not exist

I'm trying to implement basic pagination when retrieving notifications, but I get the following error.
Method
Illuminate\Notifications\DatabaseNotificationCollection::paginate does
not exist.
public function index()
{
$messages = collect();
$notifications = auth()->user()->unreadNotifications->paginate(5);
foreach ($notifications as $notification) {
$message = NotificationToMessageFactory::make($notification->type)
->toMessage($notification->data);
$messages->push($message);
}
}
You've to call paginate() on query builder instance not on a collection.
Correct syntax will be :
$notifications = auth()->user()->unreadNotifications()->paginate(5);
You should paginate before looping through the collection, otherwise you will be retrieving all records matching the query, when you only need 5. Like this:
$messages = collect();
$notifications = auth()->user()->unreadNotifications()->paginate(5);
foreach($notifications as $notification) {
$message = NotificationToMessageFactory::make($notification->type)->toMessage($notification->data);
$messages->push($message);
}

How to pass data from controller to view in Laravel

Please help me. I have these 3 tables, and I have problems on how to call the category name based on the restaurant id from Controller to view. Thank you in advance.
Table items
Table categories
Table restorant
This is my Controller
public function index()
{
if (auth()->user()->hasRole('owner')) {
$items = Items::with('category')->get();
$restorant_id = auth()->user()->restorant->id;
$category = Categories::where(['restorant_id' => $restorant_id]);
}
return view('point-of-sale::index', [
'category' => $category,
'items' => $items,
]);
}
If you add get() to the end of your $category = Categories::where(['restorant_id' => $restorant_id]); statement, you'll have an Eloquent collection returned:
$category = Categories::where(['restorant_id' => $restorant_id])->get();
Pass the $category variable to your view as you are currently, consider renaming it to $categories though just to infer that there could be multiple.
Then in your view you can loop over the Category results and access the name property:
#forelse ($category as $cat)
{{ $cat->name }}
#empty
No categories.
#endforelse
Update
If you want to get items by their category_id, you can either do as you have done with $categories:
$items = Items::where(['category_id' => $category_id])->get();
Alternatively, if you have an items relationship on your Categories model you can access them that way:
$category = Categories::with('items')
->where(['restorant_id' => $restorant_id])
->get();
The above will eager load the items related to a category which you can then access in your view, for example:
#forelse ($category as $cat)
{{ $cat->name }}
#foreach ($cat->items as $item)
{{ $item->name }}
#endforeach
#empty
No categories.
#endforelse

Laravel Eloquent Collection and Query

public function create() {
$user_id = auth()->user()->id;
$makers= Maker::all();
return view('maker.create', compact('makers'));
}
What I wanted to do is how to pass the categories name into the view but the form will accept its id. Please help.
$makers is a collection, so you need to use foreach to iterate:
#foreach ($makers as $maker)
{{ $maker->id }}
#endforeach
Update
If you want to pass it to Form::select, use pluck() method:
$makers = Maker::pluck('name', 'id');
It will generate array, which you can use:
{!! Form::select('selectName', $makers, ....) !!}

htmlentities() expects parameter 1 to be string, array given? Laravel

I've found many question realated to my problem but couldn't found an answer yet. It's about my foreach loop in my blade.
I want to print all product-names in my blade but I couln't figure out how to do that.
thats how I'm getting the products:
--- current code:
// controller
$id_array = Input::get('id');
$products= Products::whereIn('id', $id_array)->get();
$product_name = [];
foreach($products as $arr)
{
$product_name= $arr->lists('name');
}
returning $product_name gives me this as a output:
["football","cola","idontknow","freshunicorn","dummy-data"]
In my blade is just a simple:
#foreach($products as $product)
{{ $product}}
#endforeach
Error: htmlentities() expects parameter 1 to be string, array given
Thanks for your help and time.
It seems you are getting an object in an array in an array.
Like this:
array(
array(
object
)
)
It happens because you use the get() function to retrieve you model. The get() function always "wants" to retrieve multiple models. Instead you will have to use the first() function.
Like this:
foreach($id_array as $arr)
{
$want2editarray[] = Product::where('id', $arr)->first();
}
Hope it helps :)
Edit after #Wellno comment
That's probably because Product::where('id', $arr)->first(); returns null because it did not find anything.
I forgot to add a check after the retrieving of the product.
This can be done like this:
foreach($id_array as $arr)
{
// First try to get model from database
$product = Product::where('id', $arr)->first();
// If $product insert into array
if ($product) $want2editarray[] = $product;
}
Why do you use loop with IDs? You can find all products by IDs:
$products = Product::whereIn('id', $id_array)->get();
And then use $products in the blade template
#foreach($products as $product)
{{ $product->name }}
#endforeach
try to use Model/Eloquent to fetch data.
View should only display the data and not fetching directly from DB or do heavy calculations.

laravel-dompdf how to get multiple records into the data array

I have this code to try to generate a report on all records in a table:
$items = Line::all();
$data = $items->toArray();
$pdf = PDF::loadView('pdf.catalogue', $data);
return $pdf->stream();
How do I access the array in my Blade template? I have tried
#foreach ($data as $item)
but that does not work.
How you usually pass these variables into blade is by a named array, meaning you would assign it as so.
$data['items'] = $items->toArray();
In your template you should have the variables $items containing the array.
#foreach($items as $item)
...
#endforeach

Resources