2

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.

Aristona
  • 8,611
  • 9
  • 54
  • 80

4 Answers4

3

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.

Aristona
  • 8,611
  • 9
  • 54
  • 80
1

Another potential option is as follows, but I fear it's a little too much logic in the view.

@foreach ($array ?: array())
    ...
@endforeach
Dwight
  • 12,120
  • 6
  • 51
  • 64
  • This is how I could minimize it so far... but you're correct. It's unnecessary logic for a view file. – Aristona Jul 03 '13 at 18:51
1

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
Marko Aleksić
  • 1,591
  • 1
  • 18
  • 24
  • 1
    I normally do it this way, but I'm using a table.js in my projects and it automatically alerts "No records found." itself it the amount of data in 's is less than 1, so second else is often unnecessary for me. However, doing if(!empty($array)) so often feels like a bad practice use and it could be improved somehow. – Aristona Jul 01 '13 at 11:58
0

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.

pat
  • 5,757
  • 5
  • 25
  • 30
  • It already throws an exception when the variable is null, why bother throwing the same thing ourself? :p – Aristona Jul 03 '13 at 18:50