skip to Main Content

I have laravel component created in nested folders in app/view/components/modules/Exchange/common

and i use this component like this in the code:

<x-modules.Exchange.common.text-input placeholder="{{ __('Email') }}"
                                label="{{ __('Email') }}" icon="ni ni-envelope" id="email_input"
                                name="account_email" />

the problem is that component class that has constructor and default values are being ignored completely

and Laravel renders the blade.php associated with that component directly.

And of course no default values are being passed to blade, that’s why I get this error:

Error ! with http_status: 500
Undefined variable $type (View: /var/www/html/laravel/resources/views/components/modules/Exchange/common/text-input.blade.php) (View: /var/www/html/laravel/resources/views/components/modules/Exchange/common/text-input.blade.php)

In my development environment (Window) it works without any errors and the class constructor is invoked, however, when I deployed to ECS Linux I got that error.

that error occurs in all of my components.

I tried composer dum-autoload, php artisan view:clear, php artisan cache:clear, php artisan config:clear and I tried to register the component.

Can anyone help with this issue please?
I’m using on Linux

Laravel 9.41.0
PHP 8.1.2

Thanks in advance.

Edit: All of my classes comply for PSR-4
Edit:
TextInput class

<?php

namespace AppViewComponentsmodulesExchangecommon;

use IlluminateViewComponent;

class TextInput extends Component
{
    public $icon = null;

    public $name = '';

    public $placeholder = '';

    public $label = '';

    public $id = null;

    public $type = 'text';

    public $tab_index = 0;

    public $value = null;

    public $on_change = null;

    public $on_key_down = null;

    public $is_read_only;

    public $class;

    public function __construct(
        $label = '',
        $name = '',
        $icon = null,
        $placeholder = '',
        $id = null,
        $type = 'text',
        $tabIndex = 0,
        $value = null,
        $onChange = null,
        $isReadOnly = false,
        $onKeyDown = null,
        $class = '',
    ) {
        $this->icon = $icon;
        $this->name = $name;
        $this->label = $label;
        $this->placeholder = $placeholder;
        $this->id = $id;
        $this->type = $type;
        $this->tab_index = $tabIndex;
        $this->value = $value;
        $this->on_change = $onChange;
        $this->on_key_down = $onKeyDown;
        $this->is_read_only = $isReadOnly;
        $this->class = $class;
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return IlluminateContractsViewView|Closure|string
     */
    public function render()
    {
        return view('components.modules.Exchange.common.text-input');
    }
}

test-input.blade.php

<div class="form-group w-100" tabindex="">
    @if (isset($label))
        <label class="form-label" for="{{ $id }}">{{ __($label) }}</label>
    @endif
    <div class="input-group">
        @if ($icon)
            <div class="input-group-prepend">
                <span class="input-group-text"><i class="{{ $icon }}"></i></span>
            </div>
        @endif
        @if ($type != 'text_area')
            <input {{ $is_read_only ? 'readonly' : '' }} @if ($type == 'number') step="0.01" @endif
                type="{{ $type }}" name="{{ $name }}"
                @if ($id) id="{{ $id }}" @endif
                @if ($type != 'checkbox') class="form-control {{ $class }}" @endif
                placeholder="{{ __($placeholder) }}" tabindex="{{ $tab_index }}" value="{{ $value }}"
                onchange="{{ $on_change }}" onkeydown="{{ $on_key_down }}">
        @else
            <textarea {{ $is_read_only ? 'readonly' : '' }} rows="3" name="{{ $name }}"
                @if ($id) id="{{ $id }}" @endif class="form-control {{ $class }}"
                placeholder="{{ __($placeholder) }}" tabindex="{{ $tab_index }}" value="{{ $value }}"
                onchange="{{ $on_change }}" onkeydown="{{ $on_key_down }}"></textarea>
        @endif

    </div>
</div>

2

Answers


  1. Chosen as BEST ANSWER

    After searching and experementing a lot I found the solution solution.

    I was doing

    <x-modules.Exchange.common.text-input placeholder="{{ __('Email') }}"
                                    label="{{ __('Email') }}" icon="ni ni-envelope" id="email_input"
                                    name="account_email" />
    

    right?

    i need to capitalize every word in the component path like this x-Modules.Exchange.Common

    and then capitalize folders names along this path and it worked right away.

    So I'm assuming that Laravel capitalize class based components paths and try to find them then the OS comes into play, if it's case-insensetive it will find the component class and it's not (in case of linux) you have to capitalize your folders names to let the OS find it.


  2. Thanks for providing additional code snippets. Here is my updated response.

    In Laravel’s Blade templates, when using components, the component’s properties need to be passed explicitly when including the component. The default values set within the component class itself will not be automatically used if the corresponding property is not explicitly passed.

    The constructor is responsible for initializing the properties based on the values passed during component inclusion. So if you don’t pass any arguments to the constructor, it won’t use the default value you set within the class.

    You try setting your default values like this:

    class TextInputComponent extends Component
    {
        public $type;
    
        public function __construct($type = null)
        {
            $this->type = $type ?: 'text';
        }
    
        public function render()
        {
            return view('components.modules.Exchange.common.text-input');
        }
    }
    

    The line $this->type = $type ?: 'text'; utilizes the null coalescing operator (?:). It assigns the value of $type to the $type property if it is not null. However, if $type is null, it assigns the default value of 'text' to the $type property.

    This means that if you do not explicitly pass the $type attribute when including the TextInput component in your Blade template, the default value of 'text' will be used automatically.

    You may try this with the rest of your variables that you don’t want to explicitly pass a value.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search