Ember Octane Fundamentals Ember Octane Fundamentals

Event Handling with the on Modifier

Check out a free preview of the full Ember Octane Fundamentals course:
The "Event Handling with the on Modifier" Lesson is part of the full, Ember Octane Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Mike explains how to handle user interactions in Ember through the "on" modifier, which Mike adds inside of an HTML tag and uses to refer to a modifier function within the component's JavaScript module.

Get Unlimited Access Now

Transcript from the "Event Handling with the on Modifier" Lesson

[00:00:00]
>> Mike North: What we're gonna do next is deal with the idea of handling user interactions. So if you've used Ember before, this is something called actions, and in Ember Octane, they've been radically simplified. They're much easier to work with. We're gonna primarily be working in the login form. And so what we wanna do is when the user clicks the Sign In button, we wanna log the currently selected user, right?

[00:00:28] Log back to the console, and then proceed to the logged in page, right, slash teams. In order to do this, I'm going to take our login HPS which currently, there's just a bunch of HTML in there. There are no components yet. And we're gonna take this, and sort of move it all into a dedicated component where we can handle an action.

[00:00:52] Increasingly, the best practice is, you wanna handle all of your actions in components whenever possible. It is like, it's possible to handle them in other types of objects, like routes or, controllers. But increasingly, this things are heavily de-emphasized, and we just wanna keep as much of our complexity as possible in the component layer.

[00:01:18] This is setting you up for better performance and more manageability, more opportunities for lazy loading, etc. So let's begin by generating this component.
>> Mike North: Login form, Ember generate component login form.
>> Mike North: And just like earlier in the day, we're gonna grab all these handle bars, find the template that corresponds to this new component we've just created.

[00:01:52] Login form HBS and replace the contents of login form with everything that used to be in login HBS. Then we'll go back to log in HBS and refer to our component,
>> Mike North: And we see exactly the same thing on the screen, the only difference is we've just moved all of that stuff into the component.

[00:02:15] Now this is the first time we've used EmberG to generate a component. Earlier, we we're just manually creating HBS files. What we get as a result of doing that is a couple other files. And I can't find the output here, there it is. So we can see number one, we get the component itself.

[00:02:39] Sorry, that's a JavaScript module for the component, this is the first time we've seen this. We get the handlebars file that we just pasted a bunch of HTML into. And we got an integration test which works exactly the same way as our format timestamp integration test. Set up a scenario with a little handle bar snippet, assert on the HTML after it's done laundering.

[00:03:05] So, what we wanna do is listen for when someone has logged in, people have ideas for what we should listen to and where. Let me bring up the HTML to make that kinda clear.
>> Mike North: So, we've got a div up here, another div looks like just for formatting.

[00:03:31] Here we have a form, we've got a select and then an input with a submit at the bottom. Do we have more than one option or just one option? What kind of DOM event should we listen to?
>> Speaker 2: Form on submit.
>> Mike North: Form on submit. I like it.

[00:03:53] I like it because that handle's clicking on the submit button. That might handle like, if I am in an input. And I hit like command, enter or something. It seems like it handles all of the cases that might sort of merge into submitting a form. I like it.

[00:04:11] So, let's do that, and I'm going to close login HBS. And get this components JavaScript module that's an app components login-form.js. And I wanna just have these two on the screen at the same time so that we can kinda work with both of them here. So, what I wanna do is have a function that is called when the forms submit event is fired.

[00:04:41]
>> Mike North: OnLoginFormSubmit, and this is gonna receive a DOM event. And we're not using TypeScript here but we can get some nice autocomplete off awesomeness by just commenting our code properly. So I can say that evt, it is a event who's target, this is totally optional, is a HTML FormElement.

[00:05:12] It's just to make it so the autocomplete works very, very nicely.
>> Mike North: And in here, I’m just gonna put a debugger. So we can see what happens, right? So there, we’ve got our function. Now the way we hook this function up to this particular DOM event is using something called a modifier.

[00:05:34] So we dealt with helpers before. You can recognize a modifier because it’s always used in what we call HTML element space. And that means it’s kind of just floating in a DOM tag like this, right? We’re not doing, on click equals this. It’s just sort of there, side-by-side with the form tag name.

[00:05:59] You can put it anywhere in there and some attributes before, and some attributes after. But that's how you can recognize that this is a modifier and not a helper. They only are used in this particular space and the other placement is invalid. And this modifier is called on.

[00:06:21]
>> Mike North: So on we pass an event to listen to, submit as Seth said, and then we're going to pass it the function. Passing the function by value, onLoginFormSubmit. Now whenever I use this dot. This dot onLoginFormSubmit, that is a sure indicator, just from looking at the template. I can tell you that is referring to something that is defined in the JavaScript module of this component.

[00:06:58] It makes it really easy to disambiguate between things like this that we were looking at earlier when we used title and description, and the header of the channel, right? This, we know that the @ sign, that's an indication it's coming from the outside and being passed into the component.

[00:07:16] This is most certainly not being passed into the component. It is definitely defined on the component's JavaScript module itself. So this is one of the things that has improved in templates. We can look at these things and understand where the data is coming from.
>> Speaker 3: Is there no more implied this component templates?

[00:07:39]
>> Mike North: So, it will lead you into a troublesome place. And here's some examples of where that will snag you. If you have a template only component, there is no this, and so.
>> Mike North: You can end up with some kind of cryptic errors simply because you're trying to access a property off of undefined.

[00:08:04] It doesn't really give you a good place to track down where the things are coming from. So, what I recommend is using that Ember template linter. So that implied this is bend in glimmer components. Template only glimmer components and regular glimmer components with a JavaScript module behind them.

[00:08:25] It is not removed or deprecated because the older Ember component model which we're not talking about at all today. That we still need to maintain, right? These are not breaking changes at all. But, in order to set yourself up for an easy path forward, do not assume an implied this, the best way to handle things.

[00:08:53] This comes in from the outside. This is provided by the component itself. And there are cases where you will see neither of these two. And that usually means that there's some kind of callback involved, where you're sort of inside an inner scope. It's almost like a function being passed a local argument.

[00:09:13] And only within a particular chunk of your handlebars will you be able to do this. And those who have Ember experience already, each is what I'm referring to. The looping construct in Ember templates, which we will get to properly later on.