Search code examples
laravelviewlaravel-bladelaravel-livewire

How to display Json data from a method inside a livewire component into a view?


I have a livewire component method that's update a value each time a user choses a select option.

public function updatedWil()
    {
        $this->fees = DB::table('delivery_fees')
            ->select('stopdesk', 'domicile')
            ->where('destination', $this->wil)
            ->get()->toJson();
            //dd($this->fees);
        $result = response()->json($this->fees);
        return view('livewire.form-elements',compact('result'));
    }

this method above returns a two values `domicile` and `stopdesk` based on a destination selected by a user.

"[
 {"stopdesk":615,
  "domicile":1040
 }
]
"

**What am trying to do here is to send this values to my view:'livewire.form-elements' and display it on a foreach.and display it on an radio type input. **

<div class="flex items-center mb-4">
 <input checked id="default-radio-1" type="radio" wire:model="deliveryFees" value="415" class="w-4 h-4 mr-2 text-purple-400 bg-gray-100 border-gray-300 focus:ring-purple-500 dark:focus:ring-purple-500-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
            <label for="default-radio-1" class="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">Livraison
                à domicile: 415DA</label>
        </div>
        <div class="flex items-center mb-4">
            <input id="default-radio-2" type="radio" wire:model="deliveryFees" value="315" class="w-4 h-4 mr-2 text-purple-400 bg-gray-100 border-gray-300 focus:ring-purple-500 dark:focus:ring-purple-500-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
            <label for="default-radio-2" class="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">Livraison
                StopDesk:  315 DA</label>
        </div>

I tried to return it with compact method like this:

 $result = response()->json($this->fees);
 return view('livewire.form-elements',compact('result'));

and used a foreach loop with json_decode and display it in my view like this:

        @foreach (json_decode($result,true) as $items)
        <div class="flex items-center mb-4">
            <input checked id="default-radio-1" type="radio" wire:model="deliveryFees" value="415" class="w-4 h-4 mr-2 text-purple-400 bg-gray-100 border-gray-300 focus:ring-purple-500 dark:focus:ring-purple-500-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
            <label for="default-radio-1" class="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">Livraison
                à domicile: {{ $items->domicile }} DA</label>
        </div>
        <div class="flex items-center mb-4">
            <input id="default-radio-2" type="radio" wire:model="deliveryFees" value="315" class="w-4 h-4 mr-2 text-purple-400 bg-gray-100 border-gray-300 focus:ring-purple-500 dark:focus:ring-purple-500-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
            <label for="default-radio-2" class="ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">Livraison
                StopDesk: {{ $items->domicile }} DA</label>
        </div>
        @endforeach

Unfortunately it throws back an error of Undefined variable $result on view.


Solution

  • The following error:

    "must be of type: [numeric, string, array, null, or boolean]"
    

    Happens whenever you try to cast an unrecognized object to a public variable in livewire. There are two ways to work around this:

    Use a model instead of the DB helper

    So you can write your query like this:

    $this->yourPublicVariable = DeliveryFees::select('stopdesk', 'domicile')
            ->where('destination', $this->wil)
            ->get()
    

    By using a model, Livewire does know you are passing a collection, which will prevent the type error.

    Pass the variable along side the view

            $json = DB::table('delivery_fees')
            ->select('stopdesk', 'domicile')
            ->where('destination', $this->wil)
            ->get()->toJson();
    
        return view('livewire.form-elements',['json' => $json]);
    

    This way the variable is passed once, instead of having been attached to the component, downside of doing it this way is that on the next update the passed variable won't be available anymore.