I am trying to implement a private channel for the first time on Laravel and VueJS. I have gotten to the point where the event triggers as expected, but I cannot listen to it in the component that I want it to.
I followed all the steps of installing the appropriate dependencies. Can someone please tell me why this might be?
My listener:
Echo.private('message')
.listen('NewTeam', (e) => {
console.log('made it');
});
My event:
namespace App\Events;
use App\Team;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Support\Facades\Log;
class NewTeam implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* #return void
*/
public $team;
public function __construct(Team $team)
{
$this->team = $team;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('message');
}
public function broadcastWith()
{
return ["message" => 'A new team has arrived'];
}
My channel.php:
Broadcast::channel('message', function ($user) {
return true;
});
My pusher account tells me that it is sending. However, when I trigger the event, I do not receive anything from the listener.
It might be the event name that you are using. In your listener you are listening the "NewTeam" event on the message channel.
Echo.private('message')
.listen('NewTeam', (e) => { // <---
console.log('made it');
});
But in your event you aren't specifying a custom event name. According to the docs:
Broadcast Name
By default, Laravel will broadcast the event using the event's class
name. However, you may customize the broadcast name by defining a
broadcastAs method on the event:
/**
* The event's broadcast name.
*
* #return string
*/
public function broadcastAs()
{
return 'server.created';
}
So this means that the event name used in your case propably is App\\Events\\NewTeam. In order to address/custom this the way you want, you'll need to add to your event class:
app/Events/NewTeam.php
/**
* The event's broadcast name.
*
* #return string
*/
public function broadcastAs()
{
return 'NewTeam';
}
Related
I was trying to catch a fired event on my Web sockets Dashboard but my event is returning [NULL] when fired.
Please note that it is only happening in my existing project. I tried doing the same on a fresh Laravel project and it is working just fine. The event returns [] (blank array) when fired and the content of the event gets shown in the Laravel Web sockets dashboard.
Any idea on why it is returning NULL on my existing project? What can possibly be wrong.
Below is my Event file (RealTimeMessage.php)
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class RealTimeMessage implements ShouldBroadcast
{
use SerializesModels;
public $message;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct()
{
$this->message = "Hello World";
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('custom-event');
}
}
I have worked code:
Frontend code
resources/js/components/OnlineWall.vue:
mounted() {
window.Echo.channel('laravel_database_new-payload')
.listen('.new-payload-event', (e) => {
console.info('listen');
console.log(e.payload);
})
}
Event code app/Events/NewPayload.php:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Payload;
class NewPayload implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $payload;
/**
* NewPayload constructor.
* #param Payload $payload
* #return void
*/
public function __construct(Payload $payload)
{
$this->payload = $payload;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('new-payload');
}
/**
* Custom broadcast message name
*
* #return string
*/
public function broadcastAs()
{
return 'new-payload-event';
}
}
If I fire event: NewPayload::dispatch($testNewPayload); all works fine.
But I need to pass integer variable from vue component to laravel event (city_id)
if city_id is identical to city_id of Payload model from event (in $testNewPayload), then fire event . Otherwise don't fire event.
It is possible?
Channel is public, Laravel 7.0
Thank you!
Solved.
mounted() {
window.Echo.channel(`laravel_database_new-payload.${this.city_id}`)
.listen('.new-payload-event', (e) => {
console.info('listen');
console.log(e.payload);
})
}
public function broadcastOn()
{
return new Channel('new-payload.'.$this->payload->city_id);
}
I try to send notification via pusher when user submitted new order.
in my CartController where I save data into my orders table I have:
<?php
use App\Events\UserOrdered;
//codes....
public function checkout(Request $request) {
//rest of the code
Auth::user()->orders()->save($order);
event(new UserOrdered($order));
//Cart::clear();
Session::flash('success', 'Thank you. Your order has been received.');
return redirect()->route('ordersindex');
}
when I hit to save my order i will get 404 NOT FOUND on event(new UserOrdered($order));
Here is my Event code:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\Order;
class UserOrdered implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $order;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(Order $order)
{
$this->order = $order;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('order-placed');
}
}
This is my Listener code:
<?php
namespace App\Listeners;
use App\Events\UserOrdered;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendNotification
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param UserOrdered $event
* #return void
*/
public function handle(UserOrdered $event)
{
$pusher->trigger($event, 'order-placed', $order);
}
}
PS: When I try my pusher from pusher website Debug Console i can get notification. Whatever problem is, is from event and listener.
Any idea?
UPDATE
update 2
I managed to get pusher to work (i know is not the best way but it works at least).
here is my listener now:
<?php
namespace App\Listeners;
use App\Events\UserOrdered;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Pusher\Pusher;
use Mail;
class SendNotification
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param UserOrdered $event
* #return void
*/
public function handle(UserOrdered $event)
{
Mail::to($event->order->buyer_email)->send(new UserOrdered($event->order));
$options = array(
'cluster' => 'ap1',
'encrypted' => true
);
$pusher = new Pusher(
'xxxxx', //id
'xxxxx', //key
'xxxx', //secret_key
$options
);
$pusher->trigger('UserOrdered', 'order-placed', $event->order);
}
}
What I need?
Pusher will show notification in admin as new order placed. done
I also want to send 2 emails one to admin to say he/she has new
order, and another to user to say that we received his/her order.
mail function:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Order;
class UserOrdered extends Mailable
{
use Queueable, SerializesModels;
public $order;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct(Order $order)
{
$this->order = $order;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->from('noreply#tester.com')->subject('Your Order recieved!')->markdown('emails.orders');
}
}
Progress: In order to send emails I added Mail::to in my listener as you see above, and added code below to my controller function:
//rest of the code...
Auth::user()->orders()->save($order);
$user = $order->buyer_email;
event(new UserOrdered($order));
Mail::to($request->user)->send(new UserOrdered($order)); //added newly
//Cart::clear();
Session::flash('success', 'Thank you. Your order has been received.');
return redirect()->route('ordersindex');
Problem is:
I get this error
Type error: Argument 1 passed to Illuminate\Mail\PendingMail::send()
must be an instance of Illuminate\Mail\Mailable, instance of
App\Events\UserOrdered given
refers to: Mail::to($event->order->buyer_email)->send(new UserOrdered($event->order));
if I change $event->order at the end of that to something static like $event I will get:
Type error: Argument 1 passed to App\Events\UserOrdered::__construct()
must be an instance of App\Order, instance of App\Events\UserOrdered
given
any idea?
I am in the process of making realtime notifications and stumbled in this weird error. I have in my model a boot method which triggers an event called SendNotificationData (no listener). It handles when there is a new notification made.
Trial Controller
<?php
namespace App\Http\Controllers\Notification;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Models\Notification;
class NotificationController extends Controller
{
/**
* Trigger event to display notifications. This displays 404 error page
*
* #return none
*/
public function displayNotification()
{
$notification = new Notification();
$notification->EmployeeID = "EMP-00001";
$notification->NotificationText = "There is a new notification";
$notification->NotificationStatus = "unread";
$notification->NotificationType = "trial";
$notification->save();
}
}
Notification model boot method:
/**
* Handle booting of model.
*
* #var string
*/
public static function boot()
{
static::created(function ($data) {
event(new SendNotificationData($data));
});
parent::boot();
}
This is my SendNotificationData event:
namespace App\Events;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class SendNotificationData extends Event implements ShouldBroadcast
{
use SerializesModels;
public $new_notification_data;
/**
* Create a new event instance.
*
* #param $notification_data
* #return void
*/
public function __construct($new_notification_data)
{
$this->new_notification_data = $new_notification_data;
}
/**
* Get the channels the event should be broadcast on.
*
* #return array
*/
public function broadcastOn()
{
return ['new-notification'];
}
/**
* Customize event name.
*
* #return array
*/
public function broadcastAs()
{
return 'private-send-new-notification';
}
}
On Javascript
var newNotificationChannel = pusher.subscribe('new-notification');
newNotificationChannel.bind("private-send-new-notification", function(data) {
addNotification(data);
}); //This gives me no error in the console and the 404 error still shows up even if i remove this..
function addNotification(data)
{
console.log(data);
$('.notification-link').closest('li').append('This is a sample notification!!!');
}
Now, If I try to test adding some random notification in my controller, the event fires. However, it shows me the 404 error page. When I removed the ShouldBroadcast interface or remove the contents of the constructor, the error no longer shows up. I am confused what would be causing such an error when my other events are working fine. I might have missed something so please guide me.
I can't believe it, it was caused by the $incrementing variable in the model being set to false instead of true. If only laravel would show me the proper error stack trace.
I have an Event that I fire when someone favourites an entity on my system. This is fired using Event::fire(new AddedAsFav($entity_id));.
In that event I want to pull some info about that $entity_id. To do this I believe I need to pass the $entity_id as part of the constructor of my Listener and then I can access it. Unfortunately the constructor expects a type, and I can't seem to pass just an integer. The docs have lots of examples where they pass Eloquent ORM instances, which is prefixed with the name of the class (Entity $entity, for example). But I don't want to pass a full object, just an ID, as the controller it's coming from only has an ID. I'd rather do the query (which is expensive and time consuming, hence the event) in the event itself.
So how can I pass and access a basic int?
Here's my listener:
<?php
namespace App\Listeners;
use App\Events\AddedAsFav;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class GetFullEntity
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct(int $entity_id)
{
$this->entity_id = $entity_id;
}
/**
* Handle the event.
*
* #param MovieAddedAsToWatch $event
* #return void
*/
public function handle(AddedAsFav $event)
{
dd($event);
}
}
You only type cast something you may want to use in the listener.
if you want to simply access the data/object/array you passed to the event class, assign it to a public property in the event class:
class AddedAsFav extends Event
{
public $entity_id;
public function __construct($entity_id)
{
$this->entity_id = $entity_id;
}
}
You can now access it in your listener like any property:
<?php
namespace App\Listeners;
use App\Events\AddedAsFav;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class GetFullEntity
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
}
/**
* Handle the event.
*
* #param MovieAddedAsToWatch $event
* #return void
*/
public function handle(AddedAsFav $event)
{
$entity_id = $event->entity_id;
}
}
If you will have public $entity_id in you Event file, then you will be able to get that value in Listener's handle method like so: $event->entity_id.