2

I have the following event class definition:

use Symfony\Contracts\EventDispatcher\Event;

class CaseEvent extends Event
{
    public const NAME = 'case.event';

    // ...
}

And I have created a subscriber as follow:

use App\Event\CaseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class CaseEventListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [CaseEvent::NAME => 'publish'];
    }

    public function publish(CaseEvent $event): void
    {
        // do something
    }
}

I have also defined the following at services.yaml:

App\EventSubscriber\CaseEventListener:
  tags:
    - { name: kernel.event_listener, event: case.event}

Why when I dispatch such event as follow the listener method publish() is never executed?

/**
 * Added here for visibility but is initialized in the class constructor
 *
 * @var EventDispatcherInterface
 */
private $eventDispatcher;

$this->eventDispatcher->dispatch(new CaseEvent($args));

I suspect the problem is kernel.event_listener but not sure in how to subscribe the listener to the event properly.

yivi
  • 42,438
  • 18
  • 116
  • 138
ReynierPM
  • 17,594
  • 53
  • 193
  • 363
  • @yivi I might be wrong but I need to have different classes subscribed to an event, in this scenario `CaseEvent` and fire different methods like in this case is `publish()` isn't how it works? Or I am getting the whole thing wrong? – ReynierPM Aug 27 '19 at 17:11
  • Did we not just have this question? dispatch(new CaseEvent($args) will fire an event named App\Event\CaseEvent not case.event. And there no reason to add configuration for a subscriber. – Cerad Aug 27 '19 at 17:13
  • @Cerad what I am not seeing here? Even removing the subscriber config it doesn't execute the method `publish`. @yivi already had a discussion on Symfony Slack channel about that, see https://github.com/symfony/symfony/blob/4.3/src/Symfony/Component/EventDispatcher/EventDispatcher.php#L51 the parameter isn't required. I'll be contributing to docs later today by adding a note ;) – ReynierPM Aug 27 '19 at 17:16
  • 1
    Basically a dup of: https://stackoverflow.com/questions/57540654/symfony-4-custom-event-dispatcher-not-working?noredirect=1#comment101546261_57540654 And what you are missing is that the dispatch method uses the name of the event class as the event name unless you pass an explicit event name as the second arg. It is a fairly recent change. bin/console debug:event-dispatcher might help. – Cerad Aug 27 '19 at 17:18
  • 1
    Also the docs have not completely caught up with 4.3. This article might help explain what has changed and what is going on: https://symfony.com/blog/new-in-symfony-4-3-simpler-event-dispatching – Cerad Aug 27 '19 at 17:24
  • Either you pass the parameter; or you subscribe to the fq class name. In my answer I used the latter; since it’s the more modern approach. But the latter would have worked as well. – yivi Aug 27 '19 at 17:25

1 Answers1

1

Change your subscriber so getSubscribedEvents() reads like this:

public static function getSubscribedEvents(): array
{
    return [CaseEvent::class => 'publish'];
}

This takes advantage of changes on 4.3; where you no longer need to specify the event name, and makes for the simpler dispatching you are using (dispatching the event object by itself, and omitting the event name).

You could have also left your subscriber as it was; and change the dispatch call to the “old style”:

$this->eventDispatcher->dispatch(new CaseEvent($args), CaseEvent::NAME);

Also, remove the event_listener tags from services.yaml. Since you are implementing EventSubscriberInterface, you do not need to add any other configuration.

yivi
  • 42,438
  • 18
  • 116
  • 138