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.
Related
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';
}
I've created a CustomProvider, added it to the app.php array of providers and registered a class as singleton:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\ReserveCart;
class CustomProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register services.
*
* #return void
*/
public function register()
{
$this->app->singleton('App\ReserveCart', function($app){
return new ReserveCart;
});
}
}
but everytime I request for the object with $rc = resolve('App\ReserveCart'); it keeps giving me different instances of the object instead of a single one (I've done some echo tracking).
Also tried passing the dependency to methods acording to Laravel Documentation. e.g
public function foo(App\ReserveCart $rc){
//
}
but the issue persists.
Is the output below same ?
$rc = resolve('App\ReserveCart');
$rc1 = resolve('App\ReserveCart');
dd(spl_object_hash($rc), spl_object_hash($rc1));
With Laravel & Eloquent, if a column called status changes its value to "complete," for example, is it possible to automatically change the value of another column (issue_id) to NULL?
I was wondering about the set attribute or intercepting the save() method, but not sure which is best.
You could make use of Observers.
For example, to observe the Issue model, you could generate an Observer as such:
php artisan make:observer IssueObserver --model=Issue
This will produce an observer where you could listen to many model events.
<?php
namespace App\Observers;
use App\Issue;
class IssueObserver
{
/**
* Handle the Issue "updating" event.
*
* #param \App\Issue $Issue
* #return void
*/
public function updating(Issue $issue)
{
if($issue->status == 'complete') {
$issue->issue_id = null;
}
}
}
To register the Observer, you would need to add this to AppServiceProvider#boot()
<?php
namespace App\Providers;
use App\Issue;
use App\Observers\IssueObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Issue::observe(IssueObserver::class);
}
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
//
}
}
You could also just do this in your App/Issue model.
public static function boot()
{
parent::boot();
static::updating(function ($issue) {
if($issue->status == 'complete') {
$issue->issue_id = null;
}
})
}
Obviously, you would need to listen on the events that suit your needs. This is just an example. You could take a look at all the available model events here.
Not sure why I am having this issue, it should be a simple utilization of the use statement as is frequently done in Laravel controllers and repositories.
Is there something different for event listeners?
My error is:
Class 'App\Listeners\Asset' not found
It fires from my event listener:
<?php
namespace App\Listeners;
use App\Events\FFMPEGcreateAVideo;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Models\Asset;
use Auth;
use Illuminate\Support\Facades\Log;
class FFMPEGcreateAVideoListener implements ShouldQueue
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param FFMPEGcreateAVideo $event
* #return void
*/
public function handle(FFMPEGcreateAVideo $event)
{
$assetID = $event->assetID;
$assetURL = $event->assetURL;
$newAssetURL = preg_replace('/(.*\.(?!.*\.))(.*)/','${1}mp4',$assetURL);
$coverPhotoPath = $event->coverphoto;
$asset = Asset::where("id",$assetID)->first(); //error here
Edit: I've tried both composer dump-autoload and php artisan cache:clear.
Furthermore I know it is this listener.
The error in full is:
[2017-12-31 00:05:12] local.ERROR:
Symfony\Component\Debug\Exception\FatalThrowableError: Class
'App\Listeners\Asset' not found in
/var/www/html/app/Listeners/FFMPEGcreateAVideoListener.php:35 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.