Livewire: wire:click and json field casting

Created on 12 Aug 2019  Â·  3Comments  Â·  Source: livewire/livewire

Describe the bug
When using wire:click to do things, where a variable of a component is an Eloquent model that has a field being casted from json, it errors with non-object.

To Reproduce
Steps to reproduce the behavior:

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class ShowProduct extends Component
{
    public $product;

    public $in_basket = false;

    public function mount($id) {
        $this->product = \App\Product::find($id);
    }

    public function addToCart() {
        $this->in_basket = true;
    }

    public function render()
    {
        return view('livewire.show-product');
    }
}
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
// $table->json('images')
    protected $casts = [
        'images' => 'array'
    ];
}

<div class="inline-block m-2 bg-white rounded">
    <img class="" src="{{ $product->images['main'] }}">
    <div class="p-4">
        <div class="flex justify-between items-center mb-2">
            <h2 class="font-semibold text-lg uppercase text-gray-700 tracking-wider">{{ $product->name }}</h2>
            <div class="font-semibold"> 
                {{ number_format($product->cost/100, 2) }} €
            </div>
        </div>
        <div class="flex items-center justify-between">
            <div></div>
            @if(!$in_basket)
                <div class="border rounded-full px-4 text-sm tracking-wider flex items-center pt-1 font-semibold text-gray-800 cursor-pointer hover:bg-indigo-500 hover:text-white" wire:click="addToCart">
                    Lisa ostukorvi
                </div>
            @else
                <div>
                    Juba ostukorvis
                </div>
            @endif
        </div>
    </div>
</div>

Click "Lisa ostukorvi". it will 500, with Trying to get property 'images' of non-object (View: /home/rando/Documents/Sites/Storebase/resources/views/livewire/show-product.blade.php)

Expected behavior
No error, method works.

Desktop (please complete the following information):

  • Browser Chromium Version 76.0.3809.87 (Official Build) Built on Ubuntu , running on LinuxMint 19 (64-bit)

Most helpful comment

I just responded to this issue with some tactics. Take a look here: #27

All 3 comments

Hey @randohinn. I had this same issue and I'm trying to figure out the best strategy for a fix. It actually happens anytime you assign a model to a component property from within the mount function. If you move the assignment to the render function, it works correctly. ShowProduct would look like this:

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class ShowProduct extends Component
{
    public $product_id;
    public $product;
    public $in_basket = false;

    public function mount($id)
    {
        $this->product_id = $id;
    }

    public function addToCart()
    {
        $this->in_basket = true;
    }

    public function render()
    {
        $this->product = \App\Product::find($this->product_id);

        return view('livewire.show-product');
    }
}

mount is currently not called when the component dom section is reloaded and the data payload for reloading the dom section doesn't currently handle non-primatives.

Hope this helps, temporarily.

Hey @randohinn. I had this same issue and I'm trying to figure out the best strategy for a fix. It actually happens anytime you assign a model to a component property from within the mount function. If you move the assignment to the render function, it works correctly. ShowProduct would look like this:

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class ShowProduct extends Component
{
    public $product_id;
    public $product;
    public $in_basket = false;

    public function mount($id)
    {
        $this->product_id = $id;
    }

    public function addToCart()
    {
        $this->in_basket = true;
    }

    public function render()
    {
        $this->product = \App\Product::find($this->product_id);

        return view('livewire.show-product');
    }
}

mount is currently not called when the component dom section is reloaded and the data payload for reloading the dom section doesn't currently handle non-primatives.

Hope this helps, temporarily.

That does help. Wondering what @calebporzio's take is on this, is what @pddevins suggested the way to do it, or are there any plans to implement mount recalling or a way to do it my way?

I just responded to this issue with some tactics. Take a look here: #27

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mokhosh picture mokhosh  Â·  3Comments

mokhosh picture mokhosh  Â·  4Comments

tanthammar picture tanthammar  Â·  3Comments

connecteev picture connecteev  Â·  4Comments

bardh7 picture bardh7  Â·  3Comments