Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

LaCoder's avatar

Livewire component update with new data

Hello,

I need help with the Livewire component update based on the select dropdown.

<?php

namespace App\Livewire\Future;

use Carbon\Carbon;
use Livewire\Component;
use App\Models\EodFuture;

class FutureTreeMapChart extends Component
{
    public $segment = 'N50';
    public $expiry = '2024-02-25';
    public $data;

    public function fetchTreeMap()
    {
        $bn = ['HDFCBANK', 'ICICIBANK'];

        $n50 = [
            'ADANIPORTS',
            'ADANIENT',
        ];

        if (!empty($this->segment) && !empty($this->expiry)) {

            //Select for N50
            if ($this->segment == 'N50') {
                for ($i = 0; $i <= 5; $i++) {
                    $date = Carbon::today()->subDays($i)->format('Y-m-d');

                    // Check if data exists for the current date
                    if (EodFuture::whereDate('date', $date)->exists()) {
                        // If data exists for the current date, but the expiry date is gone, switch to next month
                        if (Carbon::parse($date)->endOfDay()->isPast()) {
                            $nextMonthStart = Carbon::now()->addMonth()->startOfMonth();
                            $nextMonthEnd = Carbon::now()->addMonth()->endOfMonth();
                            $this->data = EodFuture::select('asset_symbol', 'pchange')
                                ->whereIn('asset_symbol', $n50)
                                ->whereBetween('expiry', [$nextMonthStart, $nextMonthEnd])
                                ->latest('date')
                                ->orderBy('pchange', 'desc')
                                ->take(count($n50))
                                ->get();

                            break;
                        } else {
                            // If data exists for the current date and the expiry date is not yet past, return it
                            $this->data = EodFuture::select('asset_symbol', 'pchange')
                                ->whereIn('asset_symbol', $n50)
                                ->whereBetween('expiry', [now()->startOfMonth(), now()->endOfMonth()])
                                ->latest('date')
                                ->orderBy('pchange', 'desc')
                                ->take(count($n50))
                                ->get();

                            break;
                        }
                    }
                }
            }
            //Select for BN.
            else {
                for ($i = 0; $i <= 5; $i++) {
                    $date = Carbon::today()->subDays($i)->format('Y-m-d');

                    // Check if data exists for the current date
                    if (EodFuture::whereDate('date', $date)->exists()) {
                        // If data exists for the current date, but the expiry date is gone, switch to next month
                        if (Carbon::parse($date)->endOfDay()->isPast()) {
                            $nextMonthStart = Carbon::now()->addMonth()->startOfMonth();
                            $nextMonthEnd = Carbon::now()->addMonth()->endOfMonth();
                            $this->data = EodFuture::select('asset_symbol', 'pchange')
                                ->whereIn('asset_symbol', $bn)
                                ->whereBetween('expiry', [$nextMonthStart, $nextMonthEnd])
                                ->latest('date')
                                ->orderBy('pchange', 'desc')
                                ->take(count($bn))
                                ->get();
                            break;
                        } else {
                            // If data exists for the current date and the expiry date is not yet past, return it
                            $this->data = EodFuture::select('asset_symbol', 'pchange')
                                ->whereIn('asset_symbol', $bn)
                                ->whereBetween('expiry', [now()->startOfMonth(), now()->endOfMonth()])
                                ->latest('date')
                                ->orderBy('pchange', 'desc')
                                ->take(count($bn))
                                ->get();
                           
                            break;
                        }
                    }
                }
            }
        }

        $this->dispatch('dataUpdated');
    }

    public function render()
    {
        $this->fetchTreeMap();
        return view('livewire.future.future-tree-map-chart');
    }
}


Now in the component blade file,


<div class="card">
    <div class="card-header">
        <h3 class="card-title">Futures Treemap</h3>
        <div class="card-toolbar">
            <div class="d-flex align-items-center gap-2 gap-lg-3">
                <select class="form-select form-select-solid" aria-label="Select example" wire:model.live="segment">
                    <option disabled>Segment</option>
                    <option value="N50">Nifty50</option>
                    <option value="BN">BankNifty</option>
                </select>
                <select class="form-select form-select-solid" aria-label="Select example" wire:model.live="expiry">
                    <option disabled>Expiry</option>
                    <option value="2024-03-28">2024-03-28</option>
                    <option value="2024-04-25">2024-04-25</option>
                </select>
            </div>
        </div>
    </div>
    @if ($data)
        <div class="card-body" id="chart">
        </div>
    @endif
</div>
@script
    <script>
        $wire.on('dataUpdated', () => {

            var rawData = {!! $data->toJson() !!};

            console.log(rawData);
            console.log('updated');

        });
    </script>
@endscript

Whenever I change segment or expiry I can see there is an update request sent to the server and I get a response, but the problem is that rawData always logs for public $segment = 'N50';, Even if I select a different option for ```segment`` it logs for N50 only,

I did dd($this->data) on change, and it gets correct data from the database based on the selected segment, but on script, it always prints one which is selected as public property,

To me, it looks like some issues in Lifecycle, but I could not point out why rawData always get the default ```segment`` data,

What is wrong?

Thanks,

0 likes
18 replies
Snapey's avatar

how do you change segment value?

LaCoder's avatar

@Snapey Its with select,

                <select class="form-select form-select-solid" aria-label="Select example" wire:model.live="segment">
                    <option disabled>Segment</option>
                    <option value="N50">Nifty50</option>
                    <option value="BN">BankNifty</option>
                </select>

Snapey's avatar

So, some uknown code happens here

          if (!empty($this->segment) && !empty($this->expiry)) {
          .....some codes to get data from DB.
          .... 
		$this-data = DB query.

and it does not use the updated value of $this->segment?

LaCoder's avatar

@Snapey it used $this->segment, and it also get correct $this->data, but it is not passing this newly fetch data, but it send old data only, i mean one which is selected with public property.

Snapey's avatar

@LaCoder Its not possible to help without seeing what is going on.

You could install laravel debugbar and see if segment changes. Or you could share more code

LaCoder's avatar

@Snapey I have added the complete code for Component and it's blade in the original post now. It fetch correct data from DB based on selection, but in Script of blade file, it always print one which is selected in Public segment. If possible we can see via share screen, if it get difficult to explain, :-)

Snapey's avatar

@LaCoder If you don't find any matching records then data will not be modified despite taking the BN branch

LaCoder's avatar

@Snapey there are matching records and i can see matching records by dd $this ->data, even i check in Laravel debugger, i can see correct data are being fetch when selecting segment

Snapey's avatar

@LaCoder Your <script> tag is outside of the root div so nothing in the script section will change.

You could try moving the script into the component root div , or pass the updated data with the event

LaCoder's avatar

@Snapey I did move script to root div, but still same :-(, how can I connect with you directly, ?

Snapey's avatar

@LaCoder what happens if you add to your script

        $wire.on('dataUpdated', () => {

            var rawData = {!! $data->toJson() !!};

			console.log('{{ segment }}');

            console.log(rawData);
            console.log('updated');

        });
LaCoder's avatar

@Snapey It always gives N50 which is given in public property, even after changing from select. means it does not give me BN when the second option is selected,

Snapey's avatar

@LaCoder you can see in debugbar if the value changes. Livewire is not updating the javascript section of your page

LaCoder's avatar

@Snapey Yes, in Debugbar it change value and even get correct data, but in page JS it does not show correct value, so there must be a problem in passing data from component to JS, but not sure where it is?

Snapey's avatar
Snapey
Best Answer
Level 122

@LaCoder you should pass the updated data in the event.

1 like
LaCoder's avatar

@Snapey Finally!!!. I can see new data which are passed through event only, $this->dispatch('dataUpdated', $this->data, $this->segment);, there are some glitches on chart but will solve it. Thanks for help Mark Snape!

Please or to participate in this conversation.