framework: [BUG] [5.5] Component slot returns HtmlString, doesn't handle empty checks or isset properly

  • Laravel Version: v5.5.34
  • PHP Version: 7.2.0-1+ubuntu16.04.1+deb.sury.org+1
  • Database Driver & Version: N/A

Description:

EDIT: Clearer example from below comment. home.blade.php:

@component('test')
    // Not actually passing in null, this is a placeholder for something like
    // "$myObj->getLink()", which sometimes returns null
    {{null}}
@endcomponent

test.blade.php:

<div class="test">
    @empty($slot)
        {{$slot}}
    @else
        Slot not empty!
    @endif
</div>

That will render the text, “Slot not empty!”, when the value was originally null. This appears to be due to the slotted value being wrapped in an HtmlString instance, which is evaluated against (and returns false, since it is a valid instance of an object).

Steps To Reproduce:

  1. Create a component that has slots.
  2. Add an empty / isset / null check on one of the slot variables
  3. Pass that slot a null value
  4. Watch the magic

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 22 (8 by maintainers)

Most upvoted comments

To work around this, I had to do the following inside our component:

@if(isset($link) && !empty($link->toHtml()))

Hi.

I’m using:

@if($slot->isEmpty())

I’ts one of the methods of Illuminate\Support\HtmlString

Why was this closed, is it not considered an issue? I’m still using https://github.com/laravel/framework/issues/23049#issuecomment-363546052 solution, but it’s more of a workaround tbh.

@mohd-isa Read the latest comments, they explain how to circumvent the “issue”.

Re: @slot('link', $myObject->getLink()) , I’ve never seen this syntax before in the docs - a cursory glance shows the docs mention passing data in as part of the @component directive, but not into a slot like that. You are correct in that it appears to resolve my issue - Using that syntax the null is passed through without being coerced (and most importantly, handled properly).

I think the ☝️ syntax should be added to the docs, and I think it’d be a lot clearer to have a reference to why that alternate syntax is available. This doesn’t seem like such a far-out use case, and I doubt I’m the only person who’s scratched my head trying to figure out what’s happening.

If you use

@component('myComponent')
    @slot('link', $myObject->getLink())
    {{$myObject->getDescription()}}
@endcomponent

you get your desired behavior. If you don’t pass complex content to a slot, the content is passed as-is… so in this case as string.