'Component Methods error - Undefined variable in Laravel 9

I am creating a checkbox component in Laravel 9 and trying to access the isChecked method from component class as follows:

// app\View\Components\form-checkbox.php
namespace App\View\Components;
use Illuminate\View\Component;

class formcheckbox extends Component
{
    public $name;
    public $value;
    public $actualValue;

    /**
     * Create a new component instance.
     * @return void
     */
    public function __construct($name, $value, $actualValue)
    {
        //
        $this->name = $name;
        $this->value = $value;
        $this->actualValue = $actualValue;
    }

    public function isChecked($option)
    {
        return $option === $this->actualValue;
    }

    /**
     * Get the view / contents that represent the component.
     * @return \Illuminate\Contracts\View\View|\Closure|string
     */
    public function render()
    {
        return view('components.form-checkbox');
    }
}
<!-- resources\views\components\form-checkbox.blade.php -->
<div class="checkbox">
    <label>
        <input
            type="checkbox"
            name="{{ $name }}"
            value="{{ $value }}"
            actualValue={{ $actualValue }}
            {{ $isSelected($value) ? 'checked="checked"' : '' }}>
        {{ $slot }}
    </label>
</div>

When I try to render the component:

<?php $val = 'Y'; ?>
<x-form-checkbox name="testChkBx[]" value="Y" actualValue="{{ $val }}"> Y </x-form-checkbox>
<x-form-checkbox name="testChkBx[]" value="YY" actualValue="{{ $val }}"> YY </x-form-checkbox>

It gives error:

Undefined variable $isSelected.

I found one similar issue but could not find how to call the isSelected method. I am trying this with a fresh Laravel installation.



Solution 1:[1]

Errors and Fixes

You have two issues in your code:

  1. The class name.
  2. The method name.

PHP classes naming rules

A valid class name starts with a letter or underscore, followed by any number of letters, numbers, or underscores.

Component Methods Docs

In addition to public variables being available to your component template, any public methods on the component may be invoked...

Class name

For now your component is being considered as an Anonymous Component due to breaking the naming rules and conventions. Every call to an attribute or a method that exists only within the class scope will throw the Undefined error.

Beside PHP naming rules, Laravel states that a component class is named in UpperCamelCase and its view is named in kebab-case

So just recreate your component using artisan with the class name.

php artisan make:component FormCheckbox
// app\View\Components\FormCheckbox.php
class FormCheckbox extends Component
{
    public $name;
    public $value;
    public $actualValue;

    public function __construct($name, $value, $actualValue)
    {
        $this->name = $name;
        $this->value = $value;
        $this->actualValue = $actualValue;
    }

    public function isChecked($option): bool
    {
        return $option === $this->actualValue;
    }

    public function render()
    {
        return view('components.form-checkbox');
    }
}

Note that your text editor failed you and didn't point out that syntactic error!

Method name

Since you have defined an isChecked method you have to call that exact method. Because isSelected isn't a builtin method that will be available on any component, it was just an example for the docs.

<!-- resources\views\components\form-checkbox.blade.php -->
<div>
    <label>
        <input type="checkbox" name="{{ $name }}" value="{{ $value }}" actualValue={{ $actualValue }}
            {{ $isChecked($value) ? 'checked="checked"' : '' }}> {{ $slot }}
    </label>
</div>

You may need to run :

composer dump
php artisan optimize:clear

Extra

You can define the isChecked method in these ways to clean your Blade code:

<div class="checkbox">
    <label>
        <input type="checkbox" name="{{ $name }}" value="{{ $value }}" actualValue={{ $actualValue }}
            {{ $isChecked($value) }}> {{ $slot }}
    </label>
</div>

1

    public function isChecked($option): void
    {
        if ($option === $this->actualValue)
            echo 'checked="checked"';
    }

2

    public function isChecked($option): string
    {
        return $option === $this->actualValue ? 'checked="checked"' : '';
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1