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
After searching and experementing a lot I found the solution solution.
I was doing
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.
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:
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
isnull
, 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.