0
votes

I'm learning broadcasting on pizza orders tracker project. I have an admin panel where all orders are presented. Admin can update particular order

public function update(Request $re)
{
    DB::table('orderr')->where('id',$re->order)->update(['status_id'=>$re->status]);
    $user=Auth::user();
    $order=Order::find($re->order);
    event(new oscEvent($order));
    return redirect()->route('all');

}

After update oscEvent is emitted.

 class oscEvent implements ShouldBroadcast
 {
 use Dispatchable, InteractsWithSockets, SerializesModels;

/**
 * Create a new event instance.
 *
 * @return void
 */
public $order;

public function __construct($order)
{
    $this->order=$order;

}

/**
 * Get the channels the event should broadcast on.
 *
 * @return \Illuminate\Broadcasting\Channel|array
 */
public function broadcastOn()
{
    return new PrivateChannel('osc'.$this->order->id);
}

public function broadcastWith()
{
    return
    [
        'order_id'=>$this->order->id,
        'order_user_id'=>$this->order->user_id,
        'order_status_name'=>$this->order->status->name,
        'order_status_percent'=>$this->order->status->percent,


    ];
}

}

User has own panel where his orders are presented. Each order has own progressbar. Each progressbar changes without refreshing page value when admin updates the order. I use broadcasting and pusher for this. Progressbar is placed in vue component pas.vue

///User view

 foreach($orders as $o)
<tr>
<td>{{ $o->name }}</td>
<td>{{ $o->user->name }}</td>
<td>{{ $o->status->name }}</td>
<td width="50%"><pas :perc="{{ $o->status->percent }}" :order_id={{ $o->id }}></pas></td>
</tr>

///pas.vue

<template>
    <div>
   <b-progress :value="perc" :max="max" show-progress animated></b-progress>
  </div>
</template>

 export default {
data() {
return {

    max:100
};
 },
   props:['perc','order_id'],
   mounted(){

  Echo.private('osc'+this.order_id)
.listen('oscEvent', (e) => {
    this.perc=e.order_status_percent
    console.log('progressbar updated');
});

},

I'm also authorizing channel.

Broadcast::channel('osc1', function () {
///return (int) $user->id === (int) $o->user_id;
return true;
});

With public channels everything works fine. Problematic are private channels. Configuration presented above does not work fine. Pusher debug console returns api message correctly on private chanel but progressbar is not updated. Please help.

2
Is the order ID you're testing with definitely 1? Broadcast::channel('osc1', function () { will only work for order ID 1John Wedgbury

2 Answers

0
votes
  1. You need to pass the $user and $o variables into your broadcast route callback and wrap the parameter definition in curly braces:
Broadcast::channel('osc{o}', function($user, Order $o) { ... });
  1. When you don't want echo to prefix the entire event namespace to your event, you need to prefix your event name (on the front-end only) with a .:
.listen('.oscEvent', (e) ...
  1. In your oscEvent class, you should type-hint the $order parameter in the constructor:
public function __construct(Order $order) { ... }
  1. Without seeing the Echo initialization, it's hard to tell if you've configured it correctly for authentication. Did you add the csrf token to the page so echo could pick it up?

From the Laravel docs:

Laravel Echo will need access to the current session's CSRF token. You should verify that your application's head HTML element defines a meta tag containing the CSRF token:

<meta name="csrf-token" content="{{ csrf_token() }}">
  1. Make sure Broadcast::routes(); is called in your BroadcastServiceProvider::boot method.

Hope this helps.

NOTE

I'm thinking you probably do want to prefix the entire namespace to your event, so you can probably ignore suggestion #2

0
votes

It still does not work.

  1. I modified channel callback

     Broadcast::channel('osc{o}', function ($user,Order $o) {
     return (int) $user === (int) $o->user_id;
    });
    
  2. I made type-hint Order class.

  3. I'm extending "layouts.app" template in my user and admin views.
  4. Yes, it is called.

I'm using laravel 5.6.