skip to Main Content

There are many questions here that are similar to mine, such as:

but I have not found a resolution to my problem in any of them. I’ve also scoured the doc at: https://laravel.com/docs/9.x/blade#components

I would have thought this would be a simple task.

I have the following structure, in Resources/views:

start.blade.php (uses)
   components/layout.blade.php (uses)
       components/head.blade.php

From my controller, I call:

$data =
[
    'total' => $total,
    'uses_form' => true
];

return view('start', $data);

Inside start.blade.php, I have:

<x-layout>
    <x-slot name="uses_form">
        {{ $uses_form }}
    </x-slot>

    <!-- additional html -->
</x-layout>

Inside layout.blade.php:

<!DOCTYPE html>
<html lang="en">
  <x-head :uses_form:$uses_form />
  <!-- also tried: @include('includes.header', ['uses_form' => $uses_form])-->
  <body>
    <div class="container-fluid">

    {{ $slot }}

    </div><!--container-fluid-->
  </body>
</html>

Finally, in head.blade.php:

  <head>
    <link type='text/css' rel='stylesheet' href='/css/vendor/bootstrap.min.css' />
@if ($uses_form === true)
    <link type='text/css' rel='stylesheet' href='/css/form.css' />
@endif
  </head>

This results in an:

Undefined variable $uses_form

at:

head.blade.php: line 3

How can I get the variable to be recognized in head.blade.php?

I’m open to other approaches, such as generated the conditional style include, at a higher level, but I rather keep this check in head.blade.php for maintainability.

Using Laravel version 9.48.0

Edit (Additional Notes)

If I var_dump $uses_form from the top of layout.blade.php, I get the following:

object(IlluminateViewComponentSlot)#301 (2) {
 ["attributes"]=> object(IlluminateViewComponentAttributeBag)#299 (1) {
    ["attributes":protected]=> array(0) { }
    }
    ["contents":protected]=> string(1) "1"
}

So, it’s already changed form.

2

Answers


  1. Chosen as BEST ANSWER

    I got it working. There were a few things needing adjusting, but, mainly, I needed to modify the component classes to accept the parameter data.

    Another change that was needed, was to pass the data to the layout component, at the top of start.blade.php, like so:

    <x-layout :hasForm="$hasForm">
    

    Also, as indicated in another answer and in comments, I needed to place the variable in quotes.

    Finally, I'm not sure if this was part of problem, but I changed the uses_form variable from snake_case to camelCase.

    The changes, from the question are such:

    Controller:

    $data =
    [
        'total' => $total,
        'hasForm' => true
    ];
    
    return view('start', $data);
    

    start.blade.php

    <x-layout :hasForm="$hasForm">
        <!-- additional html -->
    </x-layout>
    

    app/View/Components/Layout.php

    class Layout extends Component
    {
        public $hasForm;
    
        public function __construct($hasForm)
        {
            $this->hasForm = $hasForm;
        }
    }
    

    layout.blade.php

    <!DOCTYPE html>
    <html lang="en">
      <x-head :hasForm:"$hasForm" />
      <body>
        <div class="container-fluid">
    
        {{ $slot }}
    
        </div><!--container-fluid-->
      </body>
    </html>
    

    app/Views/Components/Head.php

    class Head extends Component
    {
        public $hasForm;
    
        public function __construct($hasForm)
        {
            $this->hasForm = $hasForm;
        }
    }
    

    head.blade.php

      <head>
        <link type='text/css' rel='stylesheet' href='/css/vendor/bootstrap.min.css' />
    @if ($hasForm === true)
        <link type='text/css' rel='stylesheet' href='/css/form.css' />
    @endif
      </head>
    

    Hope this may help someone else, down the line.


  2. You can try to pass the variable $uses_form from the parent component layout.blade.php to the child component head.blade.php using following changes and I hope it will helpful to you.

    layout.blade.php look like:

    <!DOCTYPE html>
    <html lang="en">
      <x-head :uses-form="$uses_form"/>
      <body>
        <div class="container-fluid">
        {{ $slot }}
        </div><!--container-fluid-->
      </body>
    </html>
    

    head.blade.php look like:

    <head>
      <link type='text/css' rel='stylesheet' href='/css/vendor/bootstrap.min.css' />
      @if ($usesForm === true)
        <link type='text/css' rel='stylesheet' href='/css/form.css' />
      @endif
    </head>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search