Sound notification when an order comes in

What seems to be the problem:
I may not have understood how the events work yet very well, perhaps because of the parent and child components, Idk.
In my navigation bar I have 4 menu options in which in each one of them there is a component that returns the number of orders in progress (new, to be prepared, to be delivered…)
each event has a ‘refreshNumber’ listener => ‘refresh’, so far everything has worked perfectly, whenever there is a change in the order status it calls the event and update the numbers.
It happens that when trying to implement a notification sound at the arrival of a new order, the event is not called. I tried everything, since javascript, alpine js, through the components, nothing worked.

Livewire v2.3.16

`class ShowOrderNumberComponent extends Component
{
public $number;

protected $listeners = 
[
    'refreshNumber' => '$refresh',
];

public function mount()
{
    if(Auth::user()->is_admin != 1)
    {
        abort(403, 'Sem permissão!');
    }
}

public function render()
{
    $this->number = Order::whereIn('status', ['W','P'])->count();
    if($this->number == 0)
    {
        $this->number = null;
    }

    return <<<'blade'
        <div>
            <small class="inline-block align-top text-xs px-1 ml-1 bg-green-700 rounded-full text-white">
                {{$this->number}}
            </small>
        </div>
    blade;
}

}`

tried this inside:

protected $listeners = 
    [
        'refreshNumber' => '$refresh',
        'newOrder' => 'newOrder',
    ];

public function newOrder()
{
    dd(new);
}

with no success! :frowning:

I was thinking to play the sound like this:
new Audio("{{url('audio_path.mp3')}}").play();
in the script tag of admin dashboard

Anyone please can help me to understand how can I implement this, and if exist any other way to optimize my code?

Thanks a lot!

Hey, @SousaV90

Events and Listeners with simple explanation is: You are trying to fire an event and there is a method tried to listen into it in the other side.

So, In your situation you can try to listen to the event with JavaScript instead of the component.

Let’s say you have an order and when the order completed wants to play a sound, you can do something like this.

In your component:

public function completeOrder()
{
   Order::where('id', $id)->update(['status', 'completed']);

   $this->emit('orderCompleted');
}

In this case you are emitting an event, and it’s ready to listen into it in the backend or in the frontend, in our case we want it in the frontend. So, we can do something like that in the blade file (view):

<script>
     document.addEventListener("DOMContentLoaded", () => {
        @this.on('orderCompleted', () => {
            new Audio("{{url('audio_path.mp3')}}").play();
        })
     });
</script>

This is a simple example, and you can play around with it.

For more info about Events you can take a look at the docs here:

If you prefer a screencast you can also take a look here and learn from the creator:

I also tried to make a component called NewOrderComponent and included in both user and admin. But it didn’t work too. Just updated the value of play property in user, not admin. Tried to play in user just to check and everythind worked. Seems not communicating with the admin-dashboard.

Here’s the pictures:

admin.new-order-component

admin.admin-dashboard blade

Tried what you recommend:

UserShoppingCart, just for testing purposes I create a button that calls:

public function test()
    {

        //Order::where('id', $id)->update(['status', 'completed']);

        $this->emit('orderCompleted');

    }

In ShowOrderNumberComponent:

protected $listeners = 

    [

        'refreshNumber' => '$refresh',

        'orderCompleted' => 'test',

    ];

    public function mount()

    {

        if(Auth::user()->is_admin != 1)

        {

            abort(403, 'Sem permissão!');

        }

    }

    public function test()

    {

        //Order::where('id', $id)->update(['status', 'completed']);

        dd('buhhh');

        $this->emit('orderCompleted');

    }

And in AdminDashboard blade:

<script>

    document.addEventListener("DOMContentLoaded", () => {

       @this.on('orderCompleted', () => {

           new Audio("{{url('audio_path.mp3')}}").play();

       })

    });

</script>

No success…

I must have doing something stupidly wrong!

I’m very new in Livewire, and new in Laravel.

I also stopped programming for many years… unfortunately.

Read the docs but I’m having troubles to understand… :frowning:

Edit:
Maybe the problem is the path of the components?
livewire.admin and livewire.user ?!? grrr

The best practice is you don’t call the same event twice for different uses. Meaning:

Let’s assume you have post and comments components

in Post component

protected listeners = ['commentUpdated' => 'WhenCommentUpdated'];

public function whenCommentUpdated()
{
   $this->emit('playAudio');
}

In Comment Component:

public function update()
{
   // updates
  $this->emit('commentUpdated');
}

In Post blade file

posts 
<livewire:comments/>

<script>
    document.addEventListener("DOMContentLoaded", () => {

       @this.on('playAudio', () => {

           new Audio("{{url('audio_path.mp3')}}").play();

       })

    });
</script>

I hope this make sense to you.

PS: Try to follow along with the screencast and repeated if necessary until you understand how it works.

The way I have the code, I would have to include the UserShoppingCartComponent in AdminDashboarComponent, this way all the contents of the cart would be visible in admin. Is there any way to just include a specific function of UserShoppingCartComponent?
I may have to integrate things in another way so that everything works and in the best possible way.