How to hide a block if the variable is false in laravel?

I have a method in which I output the variable to the view. In the view, I check if the variable is true, then show the desired block, and if it is false, then do not show the block. But for some reason this does not work for me.

@if($mainAlbum)
   <div class="card">
      <a href="{{route('allAlbums', ['id' => $user->id])}}"><h1 class="mt-2 mb-2" style="font-size: 0.9rem; margin-left: 5px; color: black;">Плейлисты<img src="{{asset('img/right.png')}}" width="11"> </h1></a>
      @foreach($mainAlbum as $album)
          <a href="{{route('album', ['id' => $user->id, 'album' => $album->id])}}"><img src="{{$album->cover}}" class="img-fluid"></a>    
      @endforeach
   </div>
@endif

and method

public function index($id) {
    $user = User::find($id);
    $posts = $user->profile()->orderBy('created_at', 'desc')->paginate(2);
    $mainVideo = $user->profileVideo()->orderBy('created_at', 'desc')->limit(1)->get();
    $mainAlbum = $user->profileAlbums()->orderBy('created_at', 'desc')->limit(1)->get();
    return view('profile.profile', compact('user', 'posts', 'mainVideo', 'mainAlbum'));
}

Upvotes: 1

Views: 966

Answers (2)

Remul
Remul

Reputation: 8242

The problem is that get() always returns a collection, it does not matter if there is a album inside or not, therefore @if($mainAlbum) will always be truthy.

What I would do is the following:

In your controller:

public function index($id) {
    // switch 'find' with 'findOrFail' this way it will throw a 404 if no user is found
    $user = User::findOrFail($id);

    $posts = $user->profile()->orderBy('created_at', 'desc')->paginate(2);

    // use 'first' instead of 'get', so it will return a model or null instead of a collection
    $mainVideo = $user->profileVideo()->orderBy('created_at', 'desc')->first();
    $mainAlbum = $user->profileAlbums()->orderBy('created_at', 'desc')->first();

    return view('profile.profile', compact('user', 'posts', 'mainVideo', 'mainAlbum'));
}
  1. Instead of using find(), use findOrFail(), so the page will throw a 404 error if the user cannot be found.
  2. Since you are using limit(1) you can use first() instead of get(), first() will return the model or null, get() will always return a collection it does not matter if it contains a model or not.

In your view:

@if($mainAlbum)
    <div class="card">
        <a href="{{ route('allAlbums', ['id' => $user->id]) }}">
            <h1 class="mt-2 mb-2" style="font-size: 0.9rem; margin-left: 5px; color: black;">
                Плейлисты <img src="{{ asset('img/right.png') }}" width="11">
            </h1>
        </a>
        <a href="{{ route('album', ['id' => $user->id, 'album' => $mainAlbum->id]) }}">
            <img src="{{ $mainAlbum->cover }}" class="img-fluid">
        </a>
    </div>
@endif
  1. You can get rid of the @foreach since your variable will now hold the model instead of a collection
  2. Your @if check works now since $mainAlbum will contain the model or null

Upvotes: 1

Spholt
Spholt

Reputation: 4012

Before your @if () in your template, add {{ dd($mainAlbum) }}

If you are expecting the block not to display, check that returned value is falsy (i.e. null, false or 0) and not a truthy value like a string (i.e. "", "false", "null") or an Object or Array.

If you are expecting it to display, then make sure it is a truthy value.

Upvotes: 0

Related Questions