Check out a free preview of the full Ember Octane Fundamentals course:
The "Channel Footer State" 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 generates a component for the channel footer, adds actions for events related to submitting chat messages, and handles the state by controlling when the message send button is enabled or disabled.

Get Unlimited Access Now

Transcript from the "Channel Footer State" Lesson

[00:00:00]
>> Mike North: Let's look at the Channel Footer component and see what we need to do in order to take advantage of this action that we've just created. So we know createMessage is there waiting for us, and channel-footer is still a template-only component. What we can do is we can add an action in there.

[00:00:21] Even though it's a presentation component we can add an action that just serves to sort of take us from receiving a DOM event to working with the value in that input. In my mind this does not change this from being a presentation component to a smart component, or a container component.

[00:00:42] So let's go ahead and do that. We're gonna run, being very careful not to overwrite our template, ember g component,
>> Mike North: channel-footer.
>> Mike North: I'm not overriding it. All right, so now let's look at our channel footer HBS file. And we wanna look for this, there's our send button, there's our input field that's this down here, and ultimately we have a form.

[00:01:24] So it seems like we're back into the form on submit territory, familiar ground. On 'submit' this handleSubmit, something like that. Additionally, I want to be able to keep track of the current value in that input so that we can know whether to disable the button or enable it.

[00:01:49] And remember our initial approach with the login form where we were on the Submit action, that was the first time we were ever looking for what's the currently selected user? That didn't give us a nice way of having disabled versus enabled state. We need some component state that kind of keeps up to date with what's going on.

[00:02:12] It should be up here on the input, this updateMessageBody. And I expect all sorts of errors to be thrown because we have not created these functions yet.
>> Mike North: All right, and we can give it a body as well, value = this body.
>> Mike North: So what we'll need to do now is fill in, in the JavaScript module, this very limited capability that we're adding, right?

[00:02:49] This is only very local stuff-
>> Speaker 2: There's a typo, value.
>> Mike North: Value, thank you.
>> Mike North: Good catch, so we'll go to the channel footer JS module and we're gonna give ourselves a body that's gonna be tracked.
>> Mike North: We'll initialize it to an empty string,
>> Mike North: And we're gonna give ourselves an action called updateMessageBody,

[00:03:28]
>> Mike North: And this is gonna receive an event, and we're going to say this.body = evt.target.value
>> Mike North: And we can give ourselves a disabled getter.
>> Mike North: So we'll say that this form should be disabled if what?
>> Speaker 3: Body is empty string.
>> Mike North: Body is an empty string, perfect. So this body is an empty string.

[00:04:05] In fact, I'll say if it's any faulty value.
>> Mike North: So there you go, we have is disabled. This is enough that we can kind of test things out on this end, where we can replace this always disabled thing and the always gray colored with something that is conditionally applied.

[00:04:23] So disabled is this is disabled, and that will take care of the disabled attribute. And that kind of looks the background coloration. So let's replace that with if this.isDisabled you are grey, otherwise,
>> Mike North: Something like that. All right, let's try typing in this thing.
>> [SOUND]
>> Speaker 4: You need to try it in the body.

[00:04:59]
>> Mike North: I need a?
>> Speaker 4: I don't think you have the attract over your body variable?
>> Mike North: Yes, good point.
>> Mike North: Good catch, there we go. All right, the turn teal is still kind of grayed out, or opacity. Let's only dim it to 50% if it's disabled.
>> Mike North: There we go.

[00:05:25] So this to me looks like our very limited state is starting to work, and if we look at our JS module that is very, very, very simple. This is definitely a presentation-focused component. And don't be like this is a gray area, right? This is very heavy on the presentation side, but you don't need to demand that everything be a totally stateless component.

[00:05:53] Even if you can get things to where you're either 90% or greater in one direction or another, like 90% or more towards the presentation side, you already got a lot of the benefits from this kind of architecture.
>> Speaker 5: Using those curly braces inside the string, is that a new Octane feature?

[00:06:12] I remember having to use Concat and some other things, you're able to put that there, is that because it's angle bracketed?
>> Mike North: Nope, okay, here's why it looks a little different than what you're used to seeing. It has to do with the fact that we're not in a handlebars expression already.

[00:06:32]
>> Speaker 5: Okay.
>> Mike North: Right, cuz we're just in class equals. Now, this is not a component either way, it's just a button. I will say though, the fact that you've seen me do it a couple of times, that is a result of the fact that angle bracket component syntax where we're doing, just in case people don't have a reference of what old stuff looked like before.

[00:06:55] But when we invoke, when we create components like this we're not already in a handlebars expression with the double curlies. The old way of invoking components and placing them there, that was handlebars. So now this opens the door for some more flexible use, where you don't have to make everything an expression, you can just drop handlebars in a class.

[00:07:19] Yep, good observation for sure.