user5167961
user5167961

Reputation:

Laravel/Lumen event listener does not listen

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

Answers (4)

Don Kooijman
Don Kooijman

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

matejv
matejv

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

user5167961
user5167961

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

Doan Tran
Doan Tran

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

Related Questions