Reputation:
I have a Lumen controller class that fires an event when a user is created. I am using an event dispatcher. The event gets fired as it should, but the listener does not handle the event. I am sure I have followed every step of the Lumen documentation.
// UserController.php
class UserController extends ApiController
{
protected $event = null;
public function __construct(Dispatcher $event)
{
$this->event = $event;
}
/**
* Store a newly created resource in storage.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$this->acceptContentType($request, 'json');
$this->input = $request->json()->all();
$this->withEncryptedParameters();
$this->validateParameterNames(array_keys($this->validationRules));
$this->validateParameterContent($this->validationRules);
$roles = $this->getRelationInput('roles');
$user = User::create($this->input);
$this->addRelation($user, $roles, Role::class, 'roles');
$this->event->fire(new UserCreated($user));
return $this->respondCreated($user->id);
}
}
So I basically want to store a user into the database and fire an event when that happens.
// UserCreated.php
class UserCreated extends Event
{
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
}
The event is fired correctly, so if I put an "echo" or a "var_dump" into the event's constructor, I can see that it works. If I so the same for the listener, it does not react.
// UserCreatedEmail.php
class UserCreatedEmail extends Listener
{
public function handle(UserCreated $event)
{
echo 'Hello?';
}
}
I have registered it in the EventServiceProvider.
// EventServiceProvider.php
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
UserCreated::class => [
UserCreatedEmail::class
]
];
}
And uncommented it in the bootstrap area.
// bootstrap/app.php
$app->register(WISSIT\UserService\Providers\EventServiceProvider::class);
I have absolutely no idea why is doesn't work. I could use "$event->listen" but then it would also listen when I use testing. According to the Lumen documentation, it should also work without that.
And yes, the namespaces are set correctly. And no, I do not want to use Facades.
Upvotes: 4
Views: 5613
Reputation: 803
In bootstrap/app.php under 'Register Service Providers' comment out the registration of the service provider.
// $app->register(App\Providers\EventServiceProvider::class);
into
$app->register(App\Providers\EventServiceProvider::class);
Upvotes: 19
Reputation: 116
I had a similar issue when working with Lumen and event listeners. The fired event never reached my custom listener and I was struggling for a day to figure out where the problem is.
At the end I figured out, that I had a wrong signature of handle
method on my listener. It was my mistake, but Dispatcher
did not notify me about that issue. When I changed the method to accept given arguments, it just started working.
I think the problem lies in the Illuminate\Events\Dispatcher
in the fire
method. Function call_user_func_array
returns false if the signature of the method is wrong, but dispatcher just breaks out of the loop on error. And does not notify user about an issue.
Upvotes: 0
Reputation:
Okay, so it appears like the event is only listened when using \Illuminate\Contracts\Event\Dispatcher
in the controller. I used \Illuminate\Events\Dispatcher
. I don't know why that is the case, but it worked.
Upvotes: 1
Reputation: 654
I think I already got this problem, so this is how I resolve this:
In your EventServiceProvider
change the event class and listener class to a real path, dont use ::class
in EventServiceProvider
. I.e:
// EventServiceProvider.php
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'WISSIT\UserService\Events\UserCreated' => [
'WISSIT\UserService\Listeners\UserCreatedEmail'
]
];
}
Upvotes: 1