Ravi Mukti
Ravi Mukti

Reputation: 39

How To Work With Subscriber? Laravel Nwidart Modules

I'm new to using Laravel Modules, and have tried Event-Driven (via Event-Listener) but there is a little problem, where when using the subscriber method, the listener doesn't listen to events and the event is not triggered, oh yes, coincidentally the storage for the queue uses a database, is it does that also matter?

VerifiedAccountSubscriber.php

class VerifiedAccountSubscriber
{
    use Dispatchable;

    public $queue = "account";

    public function onVerifiedAccount(AccountVerified $event)
    {
        DB::transaction(function () use ($event)
        {
            /** @var \Modules\Merchant\Entities\Merchant $merchant */
            $merchant = MerchantRepository::create([
                "name" => "Merchant " . $event->user->id,
                "code" => uniqid("MERCHANT")
            ]);

            /** @var \Modules\Merchant\Entities\Location $location */
            $location = LocationRepository::create([
                "name" => "Default",
                "code" => uniqid("LOCATION"),
                "full_address" => "Default",
                "is_primary" => true
            ]);

            UserMerchantRepository::create([
                "user_id" => $event->user->id,
                "merchant_id" => $merchant->merchant_id,
                "is_primary" => true
            ]);

            MerchantLocationRepository::create([
                "merchant_id" => $merchant->merchant_id,
                "location_id" => $location->location_id
            ]);
        });
    }

    public function subscribe(Dispatcher $events)
    {
        $events->listen(
            '\Modules\Auth\Events\AccountVerified',
            '\Modules\Merchant\Listeners\VerifiedAccountSubscriber@onVerifiedAccount'
        );
    }
}

Merchant Event Service Provider

<?php

namespace Modules\Merchant\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return [];
    }

    protected $subscribe = [
        '\Modules\Merchant\Listeners\VerifiedAccountSubscriber'
    ];
}

VerifyController.php

public function verify(Request $request)
    {
        try
        {
            $userId = $request->query("user");

            $user = UserRepository::where([
                ["id", "=", $userId],
            ])->first();

            if(! URL::hasValidSignature($request))
                throw new BadRequestException(AuthError::VERIFICATION_URL_INVALID["message"], AuthError::VERIFICATION_URL_INVALID["code"]);

            if($user->hasVerifiedEmail())
                throw new BadRequestException(AuthError::EMAIL_ALREADY_VERIFIED["message"], AuthError::EMAIL_ALREADY_VERIFIED["code"]);

            $user->markEmailAsVerified();

            AccountVerified::dispatch($user);

            $apiResponse = (new ApiResponseBuilder())
                                ->setStatus(Response::HTTP_OK)
                                ->setMessage(Response::$statusTexts[Response::HTTP_OK])
                                ->build();

            return response()->json($apiResponse, Response::HTTP_OK);
        }
        catch (\Throwable $th)
        {
            throw $th;
        }
    }

AccountVerified.php

<?php

namespace Modules\Auth\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Modules\Auth\Entities\User;

class AccountVerified
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $user;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * Get the channels the event should be broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {
        return [];
    }

    public function queue()
    {
        return "account";
    }
}

Queue Runnin Queue Runnin

MerchantServiceProvider.php

Upvotes: 0

Views: 139

Answers (2)

Ravi Mukti
Ravi Mukti

Reputation: 39

After almost 1 month, and making me frustration, it turned out that the command "php artisan module:make-provider" class generated was causing problems, the weird behaviour in the nWidart/modules, the library gave me the boilerplate of EventServiceProvider class like this.

<?php

namespace Modules\Merchant\Providers;

use App\Events\AccountActivated;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return [];
    }

}

somehow that's code wont work and never ever be scanned by laravel, linting not helps. its show me the code is no error. But when i try to scan the list of listener, it's just shows me this list. event-list-wrong

After i change the class EventServiceProvider to remove the register() and the provides() method

<?php

namespace Modules\Merchant\Providers;

use App\Events\AccountActivated;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        AccountActivated::class => [
            \Modules\Merchant\Listeners\OnboardingAccountListener::class
        ]
    ];

}

Now the listener is being scanned

event-listener-work

Now Its Worked!!!!

dang

Upvotes: 0

Eyad Bereh
Eyad Bereh

Reputation: 1726

I can see multiple issues here:

  1. Your VerifiedAccountSubscriber class needs to implement the Illuminate\Contracts\Queue\ShouldQueue interface.

  2. No need to use the Illuminate\Foundation\Events\Dispatchable trait inside a listener class. This trait is used within events or jobs, but not within a listener.

  3. I also suspect that you may not be running the queue, so try to look inside the jobs and the failed_jobs table inside your database (since you're using the database driver for the queue). If you find entries inside the jobs table, it means that you need to start the queue worker using the command:

php artisan queue:work --queue=account

Upvotes: 0

Related Questions