skip to Main Content

In my scenario, I’m listening to the ‘update-selected-company’ event in a Livewire component, and upon receiving the event, I update the ‘company_id’ property. The code appears to work correctly. However, I encounter difficulties in utilizing the received value from the event in my JavaScript code. Below is the relevant code snippet:

#[On('update-selected-company')]
public function updateCompany($id)
{
    $this->js(<<<'JS'
        setTimeout(() => {
            $wire.company_id = {{ $id }};
        }, 250);
    JS);
}

Despite the seemingly correct implementation, the code does not function as expected. How can I effectively retrieve and use the ‘company_id’ value obtained from the event in my JavaScript logic?

EDITED SECTION
I have two components, Create and Company. Create has the following code:

<?php

namespace AppLivewireContacts;

use AppModelsCompany;
use AppModelsContact;
use IlluminateSupportFacadesAuth;
use LivewireAttributesComputed;
use LivewireAttributesLocked;
use LivewireAttributesOn;
use LivewireComponent;

class Create extends Component
{
  public $first_name;
  public $last_name;
  public $status;
  public $email;

  // #[Locked]
  public $company_id;

  #[Computed]
  public function companies()
  {
    return Company::get(['name', 'id']);
  }

  public function save()
  {
    $this->validate([
      'first_name' => 'required|string',
      'last_name' => 'required|string',
      'email' => 'nullable|email:rfc,dns|unique:contacts',
      'company_id' => 'required|exists:companies,id',
      'status' => 'required|in:active,in_active',
    ], [
      'company_id.exists' => 'The selected company isn't in the database.'
    ]);

    $contact = new Contact();

    $contact->first_name = $this->first_name;
    $contact->last_name = $this->last_name;
    $contact->email = $this->email;
    $contact->status = $this->status;
    $contact->company_id = $this->company_id;
    $contact->user_id = Auth::user()->id;

    $contact->save();

    $this->reset();

    return $this->redirect(Index::class);
  }

  #[On('update-selected-company')]
  public function updateCompany($id)
  {
    $this->js(<<<'JS'
      setTimeout(() => {
        $wire.company_id = $id;
      }, 250);
    JS);
  }

  public function render()
  {
    return view('livewire.contacts.create');
  }
}

The Company component has the following code:

<?php

namespace AppLivewireContacts;

use AppModelsCompany as ModelsCompany;
use LivewireComponent;

class Company extends Component
{
  public $open = false;
  public $name;

  public function addCompany()
  {
    $this->validate([
      'name' => 'required|string',
    ]);

    $company = new ModelsCompany();

    $company->name = $this->name;

    $company->save();

    $this->reset('name');

    $this->dispatch('close', modal: 'create-company');
    $this->dispatch('update-selected-company', id: $company->id)->to(Create::class);
  }

  public function render()
  {
    return view('livewire.contacts.company');
  }
}

Both of these are modals. The Company modal gets opened when a user clicks on Create a company in the Create component when a company they are looking for isn’t available in the available companies list. When a company is created the Company modal closes and then I need to update the company_id in the Create component to the newly created company and make it the current company in the select tag. Hope this helps.

2

Answers


  1. Chosen as BEST ANSWER

    So I figured out how to make this work. Here is how I did it, thanks to Wizzy from Github for pointing out that I should use heredoc instead of nowdoc:

    #[On('update-selected-company')]
     public function updateCompany($id)
     {
       $this->js(<<<JS
         let component = Livewire.getByName('contacts.create')[0]
    
         setTimeout(() => {
           component.set('company_id', $id);
         }, 50);
       JS);
     }
    

  2. It seems like you are trying to update a property called ‘company_id’ in your Livewire component using a JavaScript event. However, the way you are trying to pass the ‘id’ value from PHP to JavaScript is not correct. To effectively retrieve and use the ‘company_id’ value obtained from the event in your JavaScript logic, you can follow these steps:

    Emit the event from your Livewire component with the correct data:
    In your Livewire component, make sure you are emitting the event with the ‘company_id’ value when required. You should emit the event when you want to update the ‘company_id’ property in your JavaScript code.

    For example:

    use LivewireComponent;
    
    class YourLivewireComponent extends Component
    {
    public $company_id;
    public function updateCompany($id)
    {
        $this->company_id = $id;
    
        $this->emit('update-selected-company', $id);
    }}
    

    Listen to the Livewire event in your JavaScript:
    In your JavaScript code, you need to listen to the ‘update-selected-company’ event emitted by Livewire. You can do this by adding a Livewire listener and updating the ‘company_id’ value accordingly.

    For example:

    // Assuming you already have Livewire and it's set up properly.
    
    Livewire.on('update-selected-company', (id) => {
    // Your logic to handle the received 'id' value.
    // For example, you can update some element on the page or perform any other 
    actions with the 'id'.
    console.log('Received company_id:', id);
    });
    

    With these changes, your Livewire component should emit the ‘update-selected-company’ event when the ‘updateCompany’ method is called, and the JavaScript code will listen to this event and handle the received ‘id’ value appropriately.

    Make sure your JavaScript code is included in the view where the Livewire component is rendered so that the Livewire listener can be properly attached. Also, ensure you have initialized Livewire correctly on the page.

    Keep in mind that Livewire and JavaScript interactivity may depend on your Laravel version and configurations, so always refer to the official documentation for the version you are using to ensure the correct implementation.

    ok please try this

    <!-- Your Create component Blade view -->
    <div>
    @livewire('contacts.create')
    
    <!-- Include your JavaScript code here -->
    <script>
        // Assuming you already have Livewire and it's set up properly.
    
        document.addEventListener('livewire:dispatch', (event) => {
            if (event.detail.name === 'update-selected-company') {
                const companyId = event.detail.data.id;
                Livewire.find('contacts.create').set('company_id', 
    companyId);
            }
        });
     </script>
    

    and PHP code

    use AppModelsCompany as ModelsCompany;
    use LivewireComponent;
    
    class Company extends Component
    {
        // ... other code ...
    
        public function addCompany()
        {
            // ... your existing code to create a new company ...
    
            $this->reset('name');
    
            $this->dispatchBrowserEvent('update-selected-company', ['id' => $company->id]);
        }
    
        // ... other code ...
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search