framework: [7.x] Components with default values not working?

  • Laravel Version: 7.1.3
  • PHP Version: 7.4.1
  • Database Driver & Version: MySQL (ver. 5.5.5-10.4.11-MariaDB-1:10.4.11+maria~bionic)

Description:

I’m not able to make a component with class-based default options in my constructor for some reason.

I’ve created a repository to demonstrate my issue, viewable here: https://github.com/zack6849/component-bug

My select component works, however for some reason no matter what I pass to the blade template, the $name_field and $value_field are ALWAYS their default values.

Am I doing something wrong here? I’ll be the first to admit I’m not super caught up on the new components, but this seems strange since other default options are NOT their default options (for example, id and name are settable)

Reproduction steps:

  • Setup app as normal
  • Migrate & seed
  • Visit default route

Expected Results:

  • 2 Select elements, both with visible option text and correct IDs

Actual Results:

  • 2 Select elements, only one showing the correct option text, both showing the default IDs because ID is the default field the value is driven by

Quick snippets, just for context:

tXhTDjkejJxsAU2GZTcUd2cMQ

Select Component class:

<?php

namespace App\View\Components;

class Select extends BaseInput
{
    public $options;
    public $selected;
    public $name_field;
    public $value_field;

    /**
     * Create a new component instance.
     *
     * @param string $label
     * @param $options
     * @param string $id
     * @param string $name
     * @param $selected
     * @param bool $disabled
     * @param string $name_field
     * @param string $value_field
     */
    public function __construct($label, $options, $id = '', $name = '', $selected = null, $disabled = false, $name_field = "name", $value_field = "id")
    {
        parent::__construct($id, $name, $label, null,  $disabled);
        $this->options = $options;
        $this->selected = $selected;
        $this->name_field = $name_field;
        $this->value_field = $value_field;
        debug("End of init for select value: " . $value_field. ' name: '. $name_field . ", id: " . $id);
    }

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

    public function selected($option){
        return $option == $this->selected ? 'selected="selected" ' : '';
    }

    public function option_value($option){
        debug("Returning \$option->{$this->value_field} as value");
        return $option->{$this->value_field};
    }


    public function option_name($option){
        debug("Returning \$option->{$this->name_field} as name");
        return $option->{$this->name_field};
    }
}

Select blade component blade.php

<x-form-group>
    <label for="{{$id}}">{{$label}}</label>
    <select id="{{$id}}" class="form-control" name="{{$name}}" @if($disabled == true) disabled @endif>
        @foreach($options as $option)
            <option {{ $selected($option) }} value="{{$option_value($option)}}">{{$option_name($option)}}</option>
        @endforeach
    </select>
</x-form-group>

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 18 (9 by maintainers)

Most upvoted comments

Are you seriously saying that default values are not allowed in the constructor arguments? Are you seriously saying that if I’m using a component class with public attributes, that every single one has to have a value? It’s bad enough that I’ve wasted a substantial amount of time figuring out things in Laravel because they aren’t intuitive. Flat-out subverting basic PHP functionality and forcing developers to make workarounds that are unnecessary isn’t acceptable.