Refactor you messy code with Events & Listeners in Laravel

This post is also available in Thai:

Some of you may not notice that in order to do things well in real life, we have to break tasks down into small series of actions. We do the same when we program the computer what to do. It is like an if clause, and nothing more.

When Thirsty then Drink, When Rainy then Take an umbrella, When Sleepy then Sleep.

See? When you break down the tasks, you need no one to remind you what to do. What I am talking about is things are clearer when they are smaller.


Here it is…

Imagine you are building an e-commerce site. When someone completes and order, we send them a confirmation email. Then, we reduce the stock quantity to make sure our inventory is up to date. If it turns out that we have less than 3 items of the product in stock, we send an email to the admin to start buying more to fill the inventory up.


Base on those requirements, this is a typical code that does the job.

Simple, straightforward and nice, isn’t it?

But is there a problem with this code?

Obviously, this method is multitasking multiple things, and the code is not quite reusable.

So what’s wrong?

Let’s tear things down into actions:

  1. Order created
  2. Send confirmation email
  3. Update stock
  4. If stock is low, tell admin to fill up

In the OrderController@create, the only thing it should have to do is to create order, as it is named.

You will not see the cashier update the stock immediately once they finished your order, they keep going on next coming up customer. They only do what they are assigned to do.


Try think of those actions as pseudo code:

When order is created, send confirmation email to user, then update the stock.


When the stock is low, send admin the email that stock is low.

They are really 2 events that’s happening:

  1. Order is created
  2. Stock is low

Plus 3 actions to be done:

  1. Send confirmation email
  2. Update stock
  3. Send “stock is low” email


1. Transform the action into class

Create events:

php artisan make:event OrderCreated
php artisan make:event StockIsLow

Also listeners:

php artisan make:listener SendConfirmationEmail
php artisan make:listener UpdateStock
php artisan make:listener SendStockIsLowEmail

2. Code the events

Make your OrderCreated take an Order as a public property.

Also with StockIsLow but take a Product instead.

3. Time for listeners

Move the code into its own class, start with SendConfirmationEmail.

UpdateStock will be done as same as SendConfirmationEmail but this listener will fire another event which is StockIsLow .

then finally, SendStockIsLowEmail.


4. Register with Provider

To inform Laravel how our events and listeners are work in EventServiceProvider.php.

Notice: Laravel will sequentially compile listener as ordered in the code.

5. Simplicity is best

Take a look at your clean and clear controller. Plus you can fire the event anywhere you want.

Hmm that was not simple as I thought
More lines of code, bunch of file created, is that not more difficult to maintain?

I once believed that until I ran into a point of … you know, no one able to touch it. It can not be edited anymore, how can I say…


Apart from no more multitasking functions and make the code reusable, your code will fear no more to complex requirements.

This writing is the result of effort put in by a team at MAQE Bangkok Co., Ltd. consisting of myself, Jesada “Ohm” Maythangkul (Back End Engineer) and Wasut “Pao” Panyawiphat (Back End Engineering).

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.