DEFAULT HEADER TEXT
In this post, we are going to be taking a look at some Angular @input and @output basics to help you get a better understanding of how these commands work. A standard Angular application has many components that can nest inside each other. When one component is inside another component, we call the outer component the parent. The inner component is the child. Angular uses the @Input decorator to send data from the parent to the child, and the @Output decorator sends data from the child to the parent.
We are going to take a close look at both to see how they work and we are going to be using the Angular CLI so we can see the results of our efforts in real-time. We also begin with a new project in the CLI because it’s the easiest way for us all to start with the same code and get the same results.
If you are not familiar with the Angular CLI and you’re setting up a new project, we recommend checking out our Angular CLI – Getting Started and Angular CLI for Beginners to get up to speed.
Getting Started
Once you have the Angular CLI running and you can see the application in the browser, we can begin to work on the Angular @Input and @Output basics.
In Angular, you create components and add properties to those components. You make those properties available to child components with the Angular binding syntax decorator called @Input. An Angular decorator allows you to modify a class without changing the source code. Decorators are functions that enable a directive, service, or filter modifications. Decorators always have an @ symbol before their names — for example, @Component, @Input, and @Output.
Create a New Component
The first thing we need to do is create a new component to try our code on. This component will be the child, that will receive data from the parent, already created for us by the Angular CLI and named AppComponent. The AppComponent is in the app.component.ts file.
To create a new component for Angular, create a new file in the src/app/ folder called test-item.components.ts. You will also need to create the test-item.components.html and test-item.components.ts files in the same folder.
We cover creating a new component in another article, so to keep it simple, copy the code in Example 1 to your test-item.components.ts file and save it.
Example 1
https://gist.github.com/kevinchisholm/a5c60e749dad16f6eece5ae54da37b54
We will also copy the contents of Example 2 into our test-item.components.html file.
Example 2
https://gist.github.com/kevinchisholm/b8935d8e37a9fb9577f923e4814b30a8
Once you have these two files created and saved, we need to navigate to the app.module.ts file and change the code so it will import our child component TestItemComponent. Change the code in the app.module.ts file to look like Example 3.
Example 3
https://gist.github.com/kevinchisholm/ac9f5737e3d632931772d14905a65755
The final step in creating a child component is to navigate to the app.component.html file and add a DOM element named my-test-component. We are going to add the DOM element at line 351 for this example, and when finished, it should look like Example 4.
Example 4
https://gist.github.com/kevinchisholm/3e5595339a8c2f3022ebc672b156af6b
If everything went correctly, you should see the HTML from our new child component displayed near the top of the page in our CLI. If you didn’t understand what was going on while we were creating this component, we recommend checking out our Creating a New Component in Angular to learn more about it.
- When we run our application, the parent component AppComponent calls the child component TestItemComponent, which displays the HTML data contained within that component.
In this example, we only call the child component once, but most applications might call a child component several times, and each time, it may be required to display different data. To do that, we would need the parent component to send the new data to the child component, and that is where the @Input decorator comes in to play.
@Input
First, we’ll take a look at the @Import decorator
Import the Input Decorator
Now that we have added a new child component, we can start to work on Angular @Input and @Output basics. Let’s get started by importing the @Input decorator.
- Before we can use the @Input decorator, we need to import it from the Angular core package.
- We will import the @Input decorator on the test-item.component.ts page.
It’s easy to import the @Input decorator because we already use another decorator on this component called @Component, and that decorator also requires importing from the Angular core package, so the import statement is already in place. We only need to add Import to the statement.
To import both the component and input decorators from the Angular core package, modify your test-item.component.ts file, so the first line looks like Example 5.
Example 5
https://gist.github.com/kevinchisholm/d937c9f5b95571e43abfe61a6c31ecd5
Create a Class Property
We use @Input decorators on class properties because the property is what holds the data.
The next thing we will do is create a class property called testProperty and add it to our TestItemComponent class, as seen in Example 6.
Example 6
https://gist.github.com/kevinchisholm/225643cbf89a3dd8c3918852a03c446a
Add the Input Decorator
With the @Input decorator imported, we can use it on our new property. To make use of it, add the @input decorator to our testProperty, as seen in Example 7.
Example 7
https://gist.github.com/kevinchisholm/0469ae9d683df85315ba0339b58fc724
The @Input decorator tells Angular to support any bindings placed on any instances of the my-test-item element where the property name is testProperty.
Using the Input Decorator
To use the Input decorator, navigate to the app.components.ts page where we will create an object literal that contains data we can use. We will call the object sampleData, and the code should look like Example 8 when you are finished.
Example 8
https://gist.github.com/kevinchisholm/1aa8e670d36ad1b340498361aacdb254
- Notice that the new object sampleData which contains the new data is inside our parent component AppComponent.
- We changed the data slightly from the test-item.components.html file so you can be sure the Input decorator is working correctly.
Bind the Data
To send the data in our sampleData object to the my-test-item HTML element, we navigate back to line 351 of our app.component.html file, and we change it to look like Example 9.
Example 9
https://gist.github.com/kevinchisholm/020a639ae4d1e09cce8f8f437aa2d6d5
In Example 9, we bind the sampleData object to the testProperty property in our TestItemComponent class. This binding is taking place inside the HTML of the parent component AppComponent and is binding the data to a property of the child TestItemComponent. Our child component can now check its testProperty property to get the new data.
Use the Data
Once the sample data is bound to our child component, we can use it by navigating to the test-item-component.html file and changing the code to look like it does in Example 10.
Example 10
https://gist.github.com/kevinchisholm/4ac77bf19a12814ba08b7b4bcb8e8cbc
Once you have saved the file, if you look at the page in the browser, you can see that the TestItemComponent child class does have access to the sample data in the parent class.
@Output
Now that we have seen how to use the @Input decorator to allow a parent to communicate with the child component, let’s take a look at the @Output decorator, which enables the child to communicate with the parent component. Components can emit events in Angular using the @Output decorator, along with an Event Emitter.
Import the Output Decorator
The first thing we need to do to use the @Output decorator is to import it from the Angular core as we did with the @Input decorator. To do this, change the first line in your test-item.components.ts to look like Example 11.
Example 11
https://gist.github.com/kevinchisholm/e53dae15b521610f18e69b6b81b5b7cb
Adding the Output Decorator
We will also need to create a new property in the TestItemComponent and link it to the @Output decorator line as we did with the @Input. This time we’ll call the property in our child component delete, and you should update your code to look like example 12.
Example 12
https://gist.github.com/kevinchisholm/c21f8257e539c20cdb356298dd8bbb25
Add an Event Emitter
Output decorators work with event emitters, and you need to import them as well. Event emitters are part of the core package, so we can import them the same way we did with the others. Update the first line of your test-item,components.ts file to look like Example 13.
Example 13
https://gist.github.com/kevinchisholm/4da3dbe2068747f46b7fbe04d2d6a731
Once you have imported the event emitter, we want to set our testDelete property to a new event emitter, as we see in Example 14.
Example 14
https://gist.github.com/kevinchisholm/05d1fdcc5443a2a7a5c36fb71f5ff987
Emitting the Event
To emit an event, an action needs to take place. Assuming a click event triggers a call to an onDelete method, we will emit the output event in that method. Adjust the code in your test-item.components.ts file to look like Example 15.
Example 15
https://gist.github.com/kevinchisholm/161e42a508eca03561743bb4dd5cc67b
We have set the delete property to be an emitter, and emitters have a built-in method called emit, so we can use this.delete.emit. This method expects to return a value, which can be null, but in this case, we set it to return this.testProperty, which refers to the data we are deleting.
Use the Event
Once you have changed the code to look like Example 15, the @Output emitter in our child component is ready, and it’s time to make use of it. You need to navigate back to line 351 of the app.component.html file and change the code to look like Example 16.
Example 16
https://gist.github.com/kevinchisholm/7c068c1c3d98f5ca94913d02e41aa23f
In this example, we are binding the event in the child component to a statement called onTestPropertyDelete. Since the onDelete method returns testProperty, we can access that value using $event. So, when the my-test-item emits the delete event, we call the onTestPropertyDelete method, which exposes the data for deletion in the parent component.
All that is left is to add the onTestPropertyDelete method to our app.component.ts file. To add the method, navigate to the app.component.ts file, and change the code, so it looks like Example 17.
Example 17
https://gist.github.com/kevinchisholm/473342e6396c2613240cc15326caafe4
The onTestPropertyDelete method is in the parent component, and this is where you would place your code to handle deleting the text.
When the click event occurs, the child component sends the required data to the parent component, which does the deleting.
Conclusion
So, in closing, we hope that our discussion of Angular @Input and @Output basics has helped you get a better handle of the advantageous features of the Angular framework, and that you understand a little bit more about the communication between child components and parent components. These tools will allow your web pages and applications to be far more versatile and interactive, without adding a lot of extra code.
With the @Input decorator, you can format and present large amounts of information such as phone books or recipe books, with simple and readable code. The @Output decorator works with events such as clicks, hovers, on-load, etc. to create an extremely dynamic experience. We hope you will keep reading as we explore more ways to use Angular to develop better applications. If you have enjoyed our guide to Angular @Input and @Output basics, please share it to Facebook and Twitter.