Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepending component attributes causes an exception when said attribute is missing in calling template #35128

Closed
panda-madness opened this issue Nov 6, 2020 · 8 comments
Labels

Comments

@panda-madness
Copy link
Contributor

panda-madness commented Nov 6, 2020

  • Laravel Version: 8.13
  • PHP Version: 7.4
  • Database Driver & Version: none

Description:

Rendering a component with prepended attributes but without overriding that attribute in the calling template yields an error.

Steps To Reproduce:

  • composer create-project laravel/laravel testing
  • php artisan make:component TestComponent
  • Copy the example from the docs into the template
<div {{ $attributes->merge(['data-controller' => $attributes->prepends('profile-controller')]) }}>
    {{ $slot }}
</div>
  • attempt to render the component without 'data-controller' specified.

Rendering this component like so: <x-test-component data-controller="some-controller" /> works as expected.

Rendering this component like so: <x-test-component /> yields the following error:
Screen Shot 2020-11-06 at 13 59 09

I would expect to have the string profile-controller to be the default and only value present if no attribute named data-controller is specified.

@panda-madness panda-madness changed the title Prepending component attributes causes an exception Prepending component attributes causes an exception when said attribute is missing in calling template Nov 6, 2020
@panda-madness
Copy link
Contributor Author

panda-madness commented Nov 6, 2020

I've hotfixed this locally by adding a __toString method to AppendableAttributeValue like so:

<?php

namespace Illuminate\View;

class AppendableAttributeValue
{
    /**
     * The attribute value.
     *
     * @var mixed
     */
    public $value;

    /**
     * Create a new appendable attribute value.
     *
     * @param  mixed  $value
     * @return void
     */
    public function __construct($value)
    {
        $this->value = $value;
    }

    public function __toString()
    {
        return (string)$this->value;
    }
}

Not sure how this affects other parts of the code though.

@driesvints
Copy link
Member

Copy the example from the docs into the template

Which example?

@panda-madness
Copy link
Contributor Author

@driesvints the one from the Non-class attribute merging section. I've provided it verbatim in my original post.

@driesvints
Copy link
Member

Copy paste your TestComponent please.

@panda-madness
Copy link
Contributor Author

It's just an empty default Component stub:

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class TestComponent extends Component
{
    /**
     * Create a new component instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\Contracts\View\View|string
     */
    public function render()
    {
        return view('components.test-component');
    }
}

@driesvints
Copy link
Member

Thanks. I managed to reproduce this. I think the __toString solution is a valid one. Can you PR it? A test would be useful as well.

@panda-madness
Copy link
Contributor Author

Sure, I'll link it here when it's ready.

@panda-madness
Copy link
Contributor Author

Fixed in #35131

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants