Sometimes I get an exception just because the supply for foreach tag doesn't contain an array.
Like;
//controller
->with('array', Something::all());
//view
@foreach ($array as $k => $v)
{{ $v }}
@endforeach
If Something::all() returns null
(which is common if Something model doesn't contain any data
), foreach
will throw an exception because $array
is not actually an array, it is a NULL
.
I know we can prevent this exception with plently of ways.
Either check it in controller and push an empty array if the value is not set;
->with('array', Something::all() ?: array());
or, even do it in view files;
@if(!empty($array))
@foreach ($array as $k => $v)
{{ $v }}
@endforeach
@endif
Both will work just fine, but I really wonder what's the best practice of handling this in Laravel. In controller? In view? Somewhere else? Entirely different concept? I would like to learn the best practice uses for dealing with this.
Ps. I gave a Laravel example but non-Laravel responses are also welcome.
I have checked this in the controller, I always try to keep the logic minimal in my views.
But i could feel there could be a more Laravelish style for this, maybe use Eloquent for this with, something like this:
$model = User::findOrFail(1);
$model = User::where('votes', '>', 100)->firstOrFail();
It throws an exeption if it fails, as the method suggests.
Another potential option is as follows, but I fear it's a little too much logic in the view.
@foreach ($array ?: array())
...
@endforeach
Although, keeping logic minimal in the views is "best" practice; I would not sacrifice readability, convenience and UX for the sake of best practices.
If the data array is empty, you would probably want to display some message to the user, right? So, doing the following seems logical in view.
@if(!empty($array))
<table>
@foreach ($array as $k => $v)
<tr><td>{{ $v }}</tr></td>
@endforeach
</table>
@else:
<div class="alert">No records found.</div>
@endif
It has been a while and I believe this is the best solution so far.
@if(!$something->isEmpty())
@foreach($something as $k => $v)
...
@endforeach
@endif
The reason is, usually checks like empty/isset fails when the response is an object. They cast to true
and break the foreach.
isEmpty()
on the other hand, deals with those issues itself.