stefan storm
stefan storm

Reputation: 11

i Have a laravel 10 livewire 2 apline.js 2 component search-suggest-dropdown which works but not always giving an error Error evaluating filteredItems

the error is as follows and it only gives it to me lately i worked before and i did not chenge any code since last it worked i just stopped

error Error evaluating "filteredItems" TypeError: Cannot read properties of undefined (reading 'after')

the error occures only on this one instance of the dropdown an its used on lots of other places itested the data and it is passed to the alpine js and then it freaks out when the filterdItems gets looped over well thats what i am guessing

i have tested wiht other data if i have a few items in my array it works but when i start adding 20+ it breaks even tho if i add the same number of elements on a diffirent instance it works

Any help is appreciated have a nice day.

php code for server side

<?php

namespace App\Http\Livewire\Ui;

use Illuminate\Support\Js;
use Livewire\Component;

class SearchSuggestDropdown extends Component
{
    // this dorp down should get and set the active value
    // it should be able to have parents send data to the dropdown

    public $setOptionsListener; //a dynamic listener name can be configured for each modal
    public $returnValueListener;
    public $resetSearchListener;
    public $options = []; //all the potions the user can pick from
    public $placeholder = ''; //the place holder text of the search 
    public $search = '';
    public $open = false;

    //initializing the modal along side all of its content
    public function mount($setOptionsListener, $returnValueListener, $resetSearchListener, $initialValue, $placeholder)
    {
        $this->setOptionsListener = $setOptionsListener;
        $this->returnValueListener = $returnValueListener;
        $this->resetSearchListener = $resetSearchListener;
        $this->search = $initialValue;
        $this->placeholder = $placeholder;
    }

    //setting the Listener for the modal so we can make the modal more reusable
    protected function getListeners()
    {
        return [
            $this->setOptionsListener => 'setOptions',
            $this->resetSearchListener => 'resetSearch'
        ];
    }

    public function resetSearch()
    {
        $this->search = '';
    }

    public function updatedSearch($value)
    {
        //setting the parent value using Listeners
        $this->emit($this->returnValueListener, $this->search);
    }

    public function setOptions($options)
    {
        $this->options = '';
        $textOptions = [];
        foreach ($options as $option) {
            array_push($textOptions, '' . $option);
        }

        $this->options = $textOptions;
    }

    public function render()
    {
        return view('livewire.ui.search-suggest-dropdown');
    }
}

the front end code

{{-- this version only supports livewire usage --}}

{{-- the following should be set when the component is used --}}
{{-- (1) a child should listen to changes in the data form the parent livewire --}}
{{-- clicking on the value or pressing enter clicking or clicking outside the dropdown --}}
{{-- should pass the value to the parent --}}
{{-- the items in the x-data should be set equal to all the businesses in the db --}}

<div
x-data="{
    search: @entangle('search'),
    open: @entangle('open'),
    items: @entangle('options'),{{-- you must eco out the new transformed data to the items variable --}}

    get filteredItems() {
        return this.items.filter(
            i => i.toString().toLowerCase().includes(this.search.toString().toLowerCase())
        )
    },
}"
@mousedown.outside = "open = false"
class="flex flex-col items-center justify-center relative">

    <input @click="open = true" type="text" x-model.debounce.500ms="search" placeholder="{{ $placeholder }}" class="bg-slate-400 align-middle rounded-full w-60 text-white hover:bg-slate-500 py-2 px-5 placeholder-white">

   
    <div x-show="open" class="absolute top-12 z-10 max-h-64 overflow-y-auto overflow-x-hidden w-fit bg-slate-400 rounded-xl">
        <ul x-show="open" x-transition:enter="transition ease-out duration-300"
        x-transition:enter-start="opacity-0 translate"
        x-transition:enter-end="opacity-100 translate"
        x-transition:leave="transition ease-in duration-300"
        x-transition:leave-start="opacity-100 translate"
        x-transition:leave-end="opacity-0 translate"  class=" ">
            <template x-for="item in filteredItems" :key="item">
                <li class="align-middle rounded-full block  text-white hover:bg-slate-500 my-1 py-2 px-5 overflow-hidden" x-text="item" @click="search = item, open = false"></li>
            </template>
        </ul>
    </div>
</div>

and the code i use pass the data to the element back end

public function findAccounts()
    {
        //check if business and date is selected 
        //if not display an error
        //if they are get all the accounts for that business

        $this->hideSuccessMessage();
        $this->hideErrorMessage();

        if (!$this->selectedDate) {
            array_push($this->errorMessages, "Please select a date.");
            $this->displayErrorMessage();
            return;
        }
        if (!$this->selectedBusiness) {
            array_push($this->errorMessages, "Please select a business.");
            $this->displayErrorMessage();
            return;
        }

        //get selected business id from business array 
        $businessId = -1;
        foreach ($this->businesses as $business) {
            if ($business['name'] == $this->selectedBusiness) {
                $businessId = $business['id'];
            }
        }

        $businessAccounts = [];
        //get the accounts for the business 
        if ($businessId != -1) {
            $businessAccounts = BusinessAccount::select('id', 'account_id')->where('business_id', $businessId)->get();
        } else {
            array_push($this->errorMessages, "Please select a business for the dropdown");
            $this->displayErrorMessage();
            return;
        }

        //get all account to display the name so the user and select it 

        $databaseAccounts = [];

        foreach ($businessAccounts as $account)
        {
            array_push($databaseAccounts, $account['account_id']);
        }

        $databaseAccounts = Accounts::whereIn('id', $databaseAccounts)->get();

        foreach ($databaseAccounts as $databaseAccount) {

            foreach ($businessAccounts as $businessAccount) 
            {
                if($databaseAccount['id'] == $businessAccount['account_id'])
                {
                    array_push($this->accounts, [$databaseAccount['description'] . ' (' . $databaseAccount['account_code'] . ')', $databaseAccount['description'], $databaseAccount['account_code'], $businessAccount['id']]);
                }
            }
        }

        $this->emit('setAccountsDropdown', array_column($this->accounts, 0));
    }

and the instince of the element where i use it

@if (count($accounts))
            <div class="mt-5 flex content-center justify-center space-x-8 align-middle">
                @livewire('ui.search-suggest-dropdown', ['setOptionsListener' => 'setAccountsDropdown', 'returnValueListener' => 'setNewAccount', 'resetSearchListener' => 'resetAccountsDropdown', 'initialValue' => '', 'placeholder' => 'Search Accounts...'])
                <x-primary-button wire:click="getTransactions">
                    show
                </x-primary-button>
            </div>
        @endif

the error occures only on this one instance of the dropdown an its used on lots of other places itested the data and it is passed to the alpine js and then it freaks out when the filterdItems gets looped over well thats what i am guessing

i have tested wiht other data if i have a few items in my array it works but when i start adding 20+ it breaks even tho if i add the same number of elements on a diffirent instance it works

when clicking on the element it should show all options when searching it should only show the partial/ full matches of the search

Upvotes: 1

Views: 61

Answers (0)

Related Questions