Naming Events and Listeners0:00
Today's how-do-I episode comes courtesy of Sarah Malakot via email, who asks, What is the proper convention to use when naming your events and listeners? And this is a really common one. It can get a little tricky because everyone does it differently. So I'm going to show you my particular approach. Now, here I'm within my EventServiceProvider. You'll find that within app/Providers/EventServiceProvider.php. Now, as you may or may not know, within this array, you can define any event as well as any number of listeners who are literally listening for when that event is triggered.
Generating Event Classes0:27
you can define any event as well as any number of listeners who are literally listening for when that event is triggered. Now, it turns out that we can do this all in the manual way. So I could say, php artisan make:event, and then I could also say, php artisan make:listener. But then, once those files are created, you would have to return to this file and reference them. So something like app/Events, and then whatever the event name happens to be, which we'll talk about in a bit. And then you'll give an array of listeners.
which we'll talk about in a bit. And then you'll give an array of listeners. So app, listeners, and then listenerName. So, yeah, it can get kind of tedious to go through this process. A third option is to define your event and your listeners here, and then you can run php artisan event:generate. And here's what that's going to do. It's going to read this file, it's going to find any events you have, it's going to find any listeners you have, and it will automatically generate those files if they do not exist.
it's going to find any listeners you have, and it will automatically generate those files if they do not exist. So in this case, we called it eventName. Terrible name, don't use that. But you get the idea, right? It will automatically create both of those files. And then notice within your listener class, if we scroll down, the handle method accepts an instance of the event class. So it takes care of all that work for you rather than having to manually specify those names.
So it takes care of all that work for you rather than having to manually specify those names. Okay, but I'm going to delete those. So now that we know how to create an Event class and how to create a Listener class and then register them with Laravel's event dispatcher, how do we actually name them? Or further, when would you use an event? This can all be pretty tricky stuff until you've done it for a while and you kind of get it.
Using Events for Side Effects2:04
This can all be pretty tricky stuff until you've done it for a while and you kind of get it. Okay, so let's talk about it. Imagine, and I'll show you a few different examples, but to start, we'll do the most common one. Imagine that a User registers for your application and you handle all of that logic in your controller. But as time moves on, you keep adding more things you have to do. So it starts out with you just updating a database record and you're done. But then later, you want to send them a welcome email.
So it starts out with you just updating a database record and you're done. But then later, you want to send them a welcome email. And then you want to schedule, like, a 30-day welcome email, so just to check in on them. But then you also want to add them to Campaign Monitor or MailChimp. And then you also want to do this and that and that. It keeps growing and growing. And before you know it, your controller is kind of a nightmare. Instead, another option would be to take care of the core logic. So when a User registers, well, you've got to create a record in the table,
Instead, another option would be to take care of the core logic. So when a User registers, well, you've got to create a record in the table, you have to log them in, stuff like that. But then you have all these side effects, like I said, like scheduling an email, preparing an email for a month from now, so queuing that up, or adding them to your newsletter. I would consider all of those to be side effects. So when you do have these side effects, events are a good way to go here. So you might do this, app\Events. Now, you can namespace these if you want.
Event vs Listener Naming3:18
So you might do this, app, events. Now, you can namespace these if you want. So rather than just throwing every possible event within this folder, you could always namespace it, like your users or if it's related to your forum or anything like that. But we'll keep it in the main folder for now. And we'll say UserRegistered. Okay, so when a User registers, what needs to happen as a side effect? Well, we said app, listeners, SendWelcomeEmail. And notice, by the way, how I'm naming this.
Well, we said app, listeners, sendWelcomeEmail. And notice, by the way, how I'm naming this. So I didn't call it UserListener. This is what tons of people do. I've done it in the past as well. I've just decided that I'm not a big fan of it anymore. So adding the listener suffix there, not a huge fan of it. And it doesn't really give me too much information there. A UserListener, what does that mean that has lived for half a decade? Who knows? It could be responsible for everything.
A UserListener, what does that mean that has lived for half a decade? Who knows? It could be responsible for everything. So instead, I personally think of listener classes as almost like little procedures, little specific to-dos. So when a User registers, one to-do is to send a welcome email. So I name the class exactly in that way. And again, some people don't like this. They don't like the idea of a class taking the form of sort of like an action or a verb. Honestly, I think it's silly. I think this is a really great way to go.
It is done. It has already happened. So a general rule of thumb is to name it in the past tense. So nothing like User registers. It would be User registered. They've already done it. Okay, your listeners, once again, take the form of like a to-do item, something that you need to do. So if we were to run php artisan event:generate, it will create the event class and also three event listeners.
So if we were to run php artisan event:generate, it will create the event class and also three event listeners. So your event class, this can look a little tricky, but you know what? Actually, it's not that complicated, especially if you don't want to broadcast it to the client side. So it's beyond the scope of this lesson, you have the ability to fire an event and then also hook it up so that you can broadcast the event to your JavaScript. And then using something like Pusher or any of the services, you can listen for that exact same event name.
it's generally a good practice to queue those up because they take a lot of time. But if you're not queuing it up, well, you can get rid of the serializesModels trait as well. And now what are you left with? A plain, simple class that doesn't really do much. Now within your constructor, here is where you can accept any of the related information for the event. So if a User registered in the past, what sort of information might you want to record?
So if a User registered in the past, what sort of information might you want to record? Well, the User. What is the name of the person who registered? And then assign it. And that might be it. So your event classes are incredibly simple. It's almost like a log or a record. When you raise an event or you fire an event, and by the way, in Laravel,
When you raise an event or you fire an event, and by the way, in Laravel, you would do that with the global event function or you could also use the facade. Generally, though, I use the event function. So you might say something like new UserRegistered and then you would pass through the associated User. That fires it through the event dispatcher. And then within your ServiceProvider, that means each of these listeners will trigger,
And then within your ServiceProvider, that means each of these listeners will trigger, and as such, the handle method on each one will fire. And that way you have these isolated places to handle single bits of logic. So what is the logic for scheduling a 30-day follow-up email? You would do that here. Even if it takes the form of mail send or you reference a mailer contract that you inject, however you want to build it is fine. Now, the thing to understand is that when you fire an event,
however you want to build it is fine. Now, the thing to understand is that when you fire an event, an instance of this class itself will be sent through, once again, to the handle method. So that means the event here will be an instance of UserRegistered. So if I want to grab the user, I would do something like this. The user who signed up will be accessible through event->user. And that's how you do it. So here, yeah, this is where you would send the email to the event's user's email, and you'd prepare the view and all that stuff.
Once again, it just depends upon how you want to build it. There's no right or wrong when it comes to that. Even, like I said, when it comes to how you name these, there's no right or wrong. If you really like the idea of UserListener or UserSubscriber, where you have a class that registers the listeners and handles them, you can do that in Laravel too, by the way, through the subscribe method. I think that should do the trick. Yeah, that's an option, but still, this is what I would recommend to you. Okay, so now if we were to generate the events again, this might be a little cleaner to you.
Okay, so now if we were to generate the events again, this might be a little cleaner to you. So if you want to look for all of the listeners associated with the registration process, well, now you have a good place to do that. And once again, the handle method will still reference the proper User. So let's review one or two other naming examples, and then I think we're going to call it a day. Okay, so user registered, everyone does that. What about one other one?
More Naming Examples10:25
Okay, so User registered, everyone does that. What about one other one? I'll show you two other ones that I might use here at LaraCast. What about when a lesson was published? So a LaraCast lesson was published. Okay, well, what sort of things do you need to do there? Or first, what is the primary action? Well, the primary action, of course, is to create a new row in the database that has all the details about the lesson, maybe associate it with a Series and stuff like that.
that has all the details about the lesson, maybe associate it with a series and stuff like that. That's the core. But then you also have side effects that might be, well, any User can subscribe to a series, right? So when I add a new Lesson, there needs to be some bit of logic that filters through all of the subscribers and fires off an e-mail to them, right? So you might have a listener called emailLessonSubscribers, and then another one, and then another one.
So you might have a listener called EmailLessonSubscribers, and then another one, and then another one. That's how this stuff works. If it doesn't quite feel right to be part of the main core logic, then I will create an event listener for it. Now what else? Let's do one more. What about the forum? What do I have here? If a User replied to a conversation. Yeah, that's one. User replied to Conversation. Okay, so you're on the Layercast forum,
Yeah, that's one. User replied to Conversation. Okay, so you're on the Laracasts forum, and you reply to an existing thread or an existing Conversation. Well, actually a lot of things need to be done there. So the core, once again, is to create a new record in my replies table and associate it with the Conversation and associate it with a particular User who signed in and who wrote the post. But now the side effects might be, well, once again, you can subscribe to a thread. So I could say e-mail Conversation subscribers.
well, once again, you can subscribe to a thread. So I could say e-mail conversation subscribers. I have a class exactly like that in the Layercast code base. Another one would be, well, what about when the body of the reply says something like, Jeffrey Wei, have you seen this thread, or are you ignoring us? Yeah, so there needs to be some bit of logic that will find this. So there's some kind of regular expression in the code base that will see if you mentioned anybody, and if so, well, we need to notify them as well, whether it's through like a notification or maybe they get e-mails as well. It's just how you want to set it up.
whether it's through like a notification or maybe they get e-mails as well. It's just how you want to set it up. So here we could say if it's through e-mail, then e-mail mentioned Users could be the name of the class. And then another one would be, well, we have this concept of ExperiencePoints, mostly for fun and mostly as a metric for how active you are on the site. When you reply to a conversation, you earn a little bit of experience, and that gets added to your tally. So we might add a class here called IncrementExperience. This is how these sorts of things are taken care of, at least for Lerikas.
Wrap-Up and Q&A12:57
So we might add a class here called IncrementExperience. This is how these sorts of things are taken care of, at least for Lerikas. Okay, so that will do it for this lesson. Thank you so much to SarahMalakote for the question. If you or anyone else has a question that can possibly be answered in video form, the recommended approach is to tweet your question and then hashtag HelpMeLerikas, all one word. All right, I'll see you later.
