1
votes

I have 2 components, CastComparer and CastSearch. CastSearch are nested components within CastComparer.

Upon a certain action, the CastSearch component emits an event which CastComparer is listening for, called compare

I emit this event by doing $this->emit('compare', $this->selected);

This calls a function on my CastComparer component called makeComparison().

Below is my CastComparer component class

class CastComparer extends Component
{
    public $cast_members = [];

    protected $listeners = ['compare' => 'makeComparison'];


    public function render()
    {
        return view('livewire.cast-comparer');
    }

    public function makeComparison($id)
    {
        array_push($this->cast_members, $id);
        dd($this->cast_members);
    }
}

Below is my CastSearch component class

<?php

namespace App\Http\Livewire;

use Illuminate\Support\Facades\Http;
use Livewire\Component;

class CastSearch extends Component
{

    public $apikey = "******";

    public $query = "";

    public $results = [];

    public $selected = null;

    public $compareKey;

    public function mount()
    {
    }

    public function render()
    {
        return view('livewire.cast-search');
    }

    public function makeSelected($result_id)
    {
        $this->selected = $result_id;
        $this->results = [];
        $this->emitUp('compare', $this->selected, $this->compareKey);
    }

    public function updatedQuery()
    {
        $results = Http::get("https://api.themoviedb.org/3/search/movie?api_key={$this->apikey}&language=en-US&query={$this->query}&page=1&include_adult=true")->json();

        if ($results && array_key_exists('results', $results)) {
            $this->results = array_slice($results['results'], 0, 10);
        }
    }
}

Below is my CastSearch blade

<div class="relative">
    <input wire:model.debounce.350ms="query" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" type="text" placeholder="Member">
    <ul class="absolute rounded border shadow bg-gray-100 w-full">

        @foreach ($results as $result)
            <li class="px-4 py-2 border-b last:border-b-0 hover:bg-gray-50">
                <button type="button" wire:click="makeSelected('{{$result['id']}}')">{{$result['title']}}</button>
            </li>
        @endforeach
    </ul>
</div>

The issue I am having is, each time this is called the $cast_members array gets reset. So for example if 5 of my CastSearch components all emitted, i'd expect $cast_members array to have this

["test0", "test1", "test2", "test3", "test4"]

Instead the array seems to reset each time so I only have after the fifth emit:

["test4"]

$cast_members also has no interaction with any views so that shouldn’t affect it.

Why is it when I am emitting this event, the data in $cast_members is not retained?

Thanks

1

1 Answers

0
votes

This happen because every-time you are emitting the event the component got reinitialized ! so the array got emptied

one walk-around could be like this:

instead emitting the event everytime, you can just push those element on a public variable inside your CastSearch component, after call that event with the array after selecting all elements !

Another walk-around could be:

  public function makeComparison($id)
    {
        array_push($this->cast_members, $id);
        $this->emit('update-cast-array', $this->cast_members);
    }

just emit the updated array to your parent component ( CastSearch ) and store those value in another array, everytime you update, the array will update and store inside your parent component

Idk what is the total scenario of your work is, But I'm assuming you need need different component to this kind of task, you can simply do this type of work on the same component class.

Let me know if you are having any confusion !