Lesson Description
The "Input & Output Signals" Lesson is part of the full, Intermediate Angular: Signals & Dependency Injection course featured in this preview video. Here's what you'd learn in this lesson:
Alex demonstrates Angular's component model, focusing on parent-child component interaction. He shows how to pass data from parent to child using input decorators and introduces Angular's new signal-based inputs as a more modern alternative.
Transcript from the "Input & Output Signals" Lesson
[00:00:00]
>> Alex Okrushko: But before we dive into the code itself and steps to implement this, let me take you to my StackBlitz application, and this is what I want to show you certain new things in Angular, especially around the component model. Yes, sorry, before we go for that, having everything in one file, does that not defeat the purpose of the modular types where you have 2 or 3 people working on the same project on the same file?
[00:00:34]
So having the template as part of the component does not defeat the modular types. And if you have multiple people touching the same file, it usually doesn't matter if they even touch HTML or the component code itself, the class code itself, because if you're resolving conflicts, you'll resolve it in the HTML file or in the component file, so it shouldn't be an issue, yeah, there's no principal modular types there, the goal is to have something close to where the code is as well.
[00:01:09]
Again, in the other frameworks, say, React, right? The JSX is heavily mixing the component logic and the template itself. This is a little bit different, but again, the idea is very much the same, so the core principle here is trying to have your component templates as small as possible, and split out into more components if necessary. So, if you do have like a few thousand lines, templates and a few thousand lines component code, that should be like some bells, alarm bells, like, hey, probably he's doing too much and let's split it out.
[00:01:58]
Yeah, that's where I'm awesome, thank you. All right, so the component model is how parent and child components are interacting. So let's see what it is in the new modern Angular world. So we have, again, this is a StackBlitz, I'm going to work through this, we're not going to implement any of this, but let me just show you the demo of what I mean.
[00:02:26]
So say we have a child component, and we have a parent component here. Right, that's it, right? And then parent component will use the child component to communicate to us. So first thing first, we need to import that child. Right, if we don't import it, it's not going to work, so in this case, we have the text that we have as part of the parent, and let's add our child component which is app-child.
[00:03:00]
Right, and we do the self closing for this, so now everything works, in child we can say, hey, this is like, for example, H3, and I can say this is child, right? All right, so now, we have a parent component, we have child component, that work. Now, if we want to pass data from parent to child, historically, we would use an input decorator, so this will be input.
[00:03:44]
And then we'll say, for example, name, name, and we can even set the default value for this, right, and this is, we can interpolate this value and have the name here. From the parent side, we need to pass this name as an input, so the way we pass the input, right, with the square brackets and we have to match this name here, so we'll say name and then we'll pass the value, we'll just pass this text value.
[00:04:23]
It's a text, right? So now, our parent is passing data to a child, so this is nothing new, you've probably seen and have done it many, many times. Now, Angular introduced the concept of signals, and now and then later introduced the concept of input signals as well. So instead of using decorators like this, and in fact, you can see the components also using decorated here, those are non-standard and Angular was trying to move away from this kind of concept because it could be overlapping with native TypeScript features as well.
[00:05:10]
In fact, none of these decorators are staying in the TypeScript code. Angular compiler is going over this first and using these almost as annotations to destructure in a different format the code. And then, give it to the TypeScript to continue on. This is really powerful because again, Angular's compiler has been there for a while, you know I hear other frameworks introducing compilers, because it's such a powerful thing.
[00:05:38]
Angular had compilers since day one, in fact, that's why the templates are working, right? They try to keep it as close as possible to HTML but then we'll see how there's new things were introduced, but the having the compiler is super powerful. So, instead of having input as a decorator, Angular introduced a new input, and it's the signal-based input.
[00:06:08]
So what we can do, you can have this input and is imported from the core, so that should give you some idea that is pretty much the core of a framework now. To give the name. And this input now becomes the input signal type. Okay, the way we use signals is by calling it with parentheses, signal is an Angular primitive, which is basically store of value, and it's a reactive store of value, and you can always access that value by calling this with a parenthesis.
[00:06:55]
So in this way, name, we're going to call it and we're going to extract it. Notice I didn't change how I'm passing the input, right? It's still just a plain string, but it is passed into the input already. Now notice the other thing is right now it doesn't know that what type it is, it's unknown, I don't know what it is, so I can't really enforce it here.
[00:07:25]
If I, for example, say it's a number. Right, it would not complain saying, hey, type string is not assignable to number, so that gives us, should give us some idea that we can specify what type do we expect here as well. So in this case, we'll say it's a string. So now we can see it all working again. Now I'm a, let's take a look at this name again.
[00:07:55]
I look at the type again, so it's input signal case string or undefined. Why is it string or undefined? That means that if I don't pass anything, you can see it's still working. So at this point this input is optional. Now, if I say, hey, I really need this input from the parent, I can say I can do the required. So now you can see it's complaining and it says required input must be specified.
[00:08:35]
So, let's add it back. All right, so this is the input. How can we send the data back? We can send the data back with the output. So say I have the output. And again, I can use this output, which is also another macro since similar to input. And now it's just output of voids, if I don't provide the type, I say, hey, it's void, just some signal out, and then I can also specify the data, it needs to be a string.
[00:09:08]
Right, so instead of using the output decorator, we can just use the output signal, and you can see it's output emitter ref now. So what does it do? So, for example, let me see, for example, you can have a function, we'll call it update. And the way we'll use this output is we'll output emit. So we'll use the output emit and now we can emit something out of this component, for example, updated, updated, right?
[00:09:55]
Now, let's just add a way to output it, so I'll just quickly add the button. I'll name this button, I'll name this button update. Update and this button on the click, so we're bind to events with the parentheses, right? So we'll say, hey, when the button is clicked, update function method would be invoked. Right, so we can see it's here, you can see, I can click it, obviously doesn't work yet, we do send the output, but we're not listening for that output in the parent yet.
[00:10:45]
So in here, I can say, hey, we want the out. We have to be named exactly matching. And when this out is happening, we can just say update here as well. Update parent just to distinguish between the two. And in here I can say update parent. We can say this text. All right, so out when we're listening for the events, we need, we want to get the value from this.
[00:11:27]
So the way the value is passed is through this event, dollar event, right? That way it's now passed to this function. And in this dollar event, we'll just say new text which is string. And we'll set this text to new text. All right, let's see if it works. So what we do, what do we have here? Now, parent is listening for the child to update. Then it will also pass that data back, so we'll see the update throughout.
[00:11:52]
Stride. And we can see updated, parent got updated, child was also passed the input to update, that's a very complicated way for a child to renew the data. But again, this is just an example.
Learn Straight from the Experts Who Shape the Modern Web
- 250+In-depth Courses
- Industry Leading Experts
- 24Learning Paths
- Live Interactive Workshops