Search code examples
phplaravellaravel-livewire

"Attempt to read property "id" on array" when changing values on a <select>


I'm having this bug using livewire and I really don't see what's the problem

In the class, I have a $dominio_id public variable declared where my component will bind. I have also a $dominios variable where I'm getting the data from the Dominio model, something as simple as...

class Software extends Component {
  public $dominio_id, $dominios; 
  ...

  public function mount() {
    $this->dominios = Dominio::orderBy('name')->get();
    $this->dominio_id = 1;
    ...
  }
}

In the blade, I have the following:

<select wire:model="dominio_id">
    @foreach ($dominios as $d)
        <option value="{{ $d->id }}">{{ $d->path }}</option>
    @endforeach
</select>

It renders fine, if I change the dominio_id to whatever id in the table, it gets selected, so no problems. Now, when I select a different value, it throws the error: Attempt to read property "id" on array the trace says the problem is here:

<option value="{{ $d->id }}">{{ $d->path }}</option>

If I take out the wire:model the problem goes away, but of course I can't bind the select.

I have done this very same thing lots of times, and never encountered this kind of error.

I tried also, while I know it isn't needed to add a $rules var:

protected $rules = [
  'dominio_id' => 'required',
];

But doesn't work either.

If I use the inspect tool, I see the select - option is well formed:

Any idea?


Solution

  • You have two options to solve that (one of these two options is enough):

    1: remove $this->dominios from mount() and added in render() like this:

    public function render(){
    $dominios = Dominio::orderBy('name')->get();
    return view('your-view',compact('dominios'));
    }
    

    2: in your blade you must use array instead of collection, like this:

    <select wire:model="dominio_id">
        @foreach ($dominios as $d)
            <option value="{{ $d['id'] }}">{{ $d['path'] }}</option>
        @endforeach
    </select>
    

    the reason is livewire can't pass parameters by collection type to views (because js can't render that) , so when you use collection in mount(), livewire converted collection to array in next request.