2020-10-05 17:05:28 -04:00
# Sharing data between child and parent directives and components
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
A common pattern in Angular is sharing data between a parent component and one or more child components.
2021-07-26 22:54:19 +03:00
To implement this pattern use the `@Input()` and `@Output()` decorators.
2020-04-28 16:26:58 -04:00
<div class="alert is-helpful">
See the <live-example></live-example> for a working example containing the code snippets in this guide.
</div>
2020-10-05 17:05:28 -04:00
Consider the following hierarchy:
2020-04-28 16:26:58 -04:00
``` html
< parent-component >
< child-component > < / child-component >
< / parent-component >
```
2020-10-05 17:05:28 -04:00
The `<parent-component>` serves as the context for the `<child-component>` .
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
`@Input()` and `@Output()` give a child component a way to communicate with its parent component.
2021-07-21 05:01:39 +00:00
`@Input()` lets a parent component update data in the child component.
Conversely, `@Output()` lets the child send data to a parent component.
2020-04-28 16:26:58 -04:00
{@a input}
2020-10-05 17:05:28 -04:00
## Sending data to a child component
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The `@Input()` decorator in a child component or directive signifies that the property can receive its value from its parent component.
2020-04-28 16:26:58 -04:00
<div class="lightbox">
2021-03-19 16:44:28 -04:00
<img src="generated/images/guide/inputs-outputs/input.svg" alt="Input data flow diagram of data flowing from parent to child">
2020-04-28 16:26:58 -04:00
</div>
2020-10-05 17:05:28 -04:00
To use `@Input()` , you must configure the parent and child.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
### Configuring the child component
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
To use the `@Input()` decorator in a child component class, first import `Input` and then decorate the property with `@Input()` , as in the following example.
2020-04-28 16:26:58 -04:00
<code-example path="inputs-outputs/src/app/item-detail/item-detail.component.ts" region="use-input" header="src/app/item-detail/item-detail.component.ts"></code-example>
2020-10-05 17:05:28 -04:00
In this case, `@Input()` decorates the property <code class="no-auto-link">item</code>, which has a type of `string` , however, `@Input()` properties can have any type, such as `number` , `string` , `boolean` , or `object` .
The value for `item` comes from the parent component.
2020-04-28 16:26:58 -04:00
Next, in the child component template, add the following:
<code-example path="inputs-outputs/src/app/item-detail/item-detail.component.html" region="property-in-template" header="src/app/item-detail/item-detail.component.html"></code-example>
2020-10-05 17:05:28 -04:00
### Configuring the parent component
2020-04-28 16:26:58 -04:00
The next step is to bind the property in the parent component's template.
In this example, the parent component template is `app.component.html` .
2020-10-05 17:05:28 -04:00
1. Use the child's selector, here `<app-item-detail>` , as a directive within the
parent component template.
2. Use [property binding ](guide/property-binding ) to bind the `item` property in the child to the `currentItem` property of the parent.
2020-04-28 16:26:58 -04:00
<code-example path="inputs-outputs/src/app/app.component.html" region="input-parent" header="src/app/app.component.html"></code-example>
2020-10-05 17:05:28 -04:00
3. In the parent component class, designate a value for `currentItem` :
2020-04-28 16:26:58 -04:00
<code-example path="inputs-outputs/src/app/app.component.ts" region="parent-property" header="src/app/app.component.ts"></code-example>
With `@Input()` , Angular passes the value for `currentItem` to the child so that `item` renders as `Television` .
The following diagram shows this structure:
<div class="lightbox">
2021-03-19 16:44:28 -04:00
<img src="generated/images/guide/inputs-outputs/input-diagram-target-source.svg" alt="Property binding diagram of the target, item, in square brackets set to the source, currentItem, on the right of an equal sign">
2020-04-28 16:26:58 -04:00
</div>
2020-10-05 17:05:28 -04:00
The target in the square brackets, `[]` , is the property you decorate with `@Input()` in the child component.
The binding source, the part to the right of the equal sign, is the data that the parent component passes to the nested component.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
### Watching for `@Input()` changes
2020-04-28 16:26:58 -04:00
2021-07-21 05:01:39 +00:00
To watch for changes on an `@Input()` property, use `OnChanges` , one of Angular's [lifecycle hooks ](guide/lifecycle-hooks ).
2020-10-05 17:05:28 -04:00
See the [`OnChanges` ](guide/lifecycle-hooks#onchanges ) section of the [Lifecycle Hooks ](guide/lifecycle-hooks ) guide for more details and examples.
2020-04-28 16:26:58 -04:00
{@a output}
2020-10-05 17:05:28 -04:00
## Sending data to a parent component
2020-04-28 16:26:58 -04:00
2021-07-21 05:01:39 +00:00
The `@Output()` decorator in a child component or directive lets data flow from the child to the parent.
2020-04-28 16:26:58 -04:00
<div class="lightbox">
2021-03-19 16:44:28 -04:00
<img src="generated/images/guide/inputs-outputs/output.svg" alt="Output diagram of the data flow going from child to parent">
2020-04-28 16:26:58 -04:00
</div>
2020-10-05 17:05:28 -04:00
`@Output()` marks a property in a child component as a doorway through which data can travel from the child to the parent.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The child component uses the `@Output()` property to raise an event to notify the parent of the change.
To raise an event, an `@Output()` must have the type of `EventEmitter` , which is a class in `@angular/core` that you use to emit custom events.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The following example shows how to set up an `@Output()` in a child component that pushes data from an HTML `<input>` to an array in the parent component.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
To use `@Output()` , you must configure the parent and child.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
### Configuring the child component
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The following example features an `<input>` where a user can enter a value and click a `<button>` that raises an event. The `EventEmitter` then relays the data to the parent component.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
1. Import `Output` and `EventEmitter` in the child component class:
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
```js
import { Output, EventEmitter } from '@angular/core';
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
` ``
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
1. In the component class, decorate a property with ` @Output ()`.
The following example ` newItemEvent` ` @Output ()` has a type of ` EventEmitter`, which means it's an event.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
<code-example path="inputs-outputs/src/app/item-output/item-output.component.ts" region="item-output" header="src/app/item-output/item-output.component.ts"></code-example>
2020-04-28 16:26:58 -04:00
2021-07-21 05:01:39 +00:00
The different parts of the preceding declaration are as follows:
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
* ` @Output ()`—a decorator function marking the property as a way for data to go from the child to the parent
* ` newItemEvent`—the name of the ` @Output ()`
* ` EventEmitter<string>`—the ` @Output ()`'s type
* ` new EventEmitter<string>()`—tells Angular to create a new event emitter and that the data it emits is of type string.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
For more information on ` EventEmitter`, see the [EventEmitter API documentation](api/core/EventEmitter).
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
1. Create an ` addNewItem()` method in the same component class:
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
<code-example path="inputs-outputs/src/app/item-output/item-output.component.ts" region="item-output-class" header="src/app/item-output/item-output.component.ts"></code-example>
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The ` addNewItem()` function uses the ` @Output ()`, ` newItemEvent`, to raise an event with the value the user types into the ` <input>`.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
### Configuring the child's template
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The child's template has two controls.
The first is an HTML ` <input>` with a [template reference variable](guide/template-reference-variables) , ` #newItem `, where the user types in an item name.
The ` value` property of the ` #newItem ` variable stores what the user types into the ` <input>`.
2020-04-28 16:26:58 -04:00
<code-example path="inputs-outputs/src/app/item-output/item-output.component.html" region="child-output" header="src/app/item-output/item-output.component.html"></code-example>
2020-10-05 17:05:28 -04:00
The second element is a ` <button>` with a ` click` [event binding](guide/event-binding).
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The ` (click)` event is bound to the ` addNewItem()` method in the child component class.
The ` addNewItem()` method takes as its argument the value of the ` #newItem .value` property.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
### Configuring the parent component
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The ` AppComponent` in this example features a list of ` items` in an array and a method for adding more items to the array.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
<code-example path="inputs-outputs/src/app/app.component.ts" region="add-new-item" header="src/app/app.component.ts"></code-example>
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The ` addItem()` method takes an argument in the form of a string and then adds that string to the ` items` array.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
### Configuring the parent's template
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
1. In the parent's template, bind the parent's method to the child's event.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
1. Put the child selector, here ` <app-item-output>`, within the parent component's template, ` app.component.html`.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
<code-example path="inputs-outputs/src/app/app.component.html" region="output-parent" header="src/app/app.component.html"></code-example>
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The event binding, ` (newItemEvent)='addItem($event)'`, connects the event in the child, ` newItemEvent`, to the method in the parent, ` addItem()`.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The ` $event` contains the data that the user types into the ` <input>` in the child template UI.
2020-04-28 16:26:58 -04:00
2021-07-21 05:01:39 +00:00
To see the ` @Output ()` working, add the following to the parent's template:
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
` ``html
<ul>
<li *ngFor="let item of items">{{item}}</li>
</ul>
2020-04-28 16:26:58 -04:00
` ``
2020-10-05 17:05:28 -04:00
The ` *ngFor` iterates over the items in the ` items` array.
When you enter a value in the child's ` <input>` and click the button, the child emits the event and the parent's ` addItem()` method pushes the value to the ` items` array and new item renders in the list.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
## Using ` @Input ()` and ` @Output ()` together
2020-04-28 16:26:58 -04:00
2021-07-21 05:01:39 +00:00
Use ` @Input ()` and ` @Output ()` on the same child component as follows:
2020-04-28 16:26:58 -04:00
<code-example path="inputs-outputs/src/app/app.component.html" region="together" header="src/app/app.component.html"></code-example>
2020-10-05 17:05:28 -04:00
The target, ` item`, which is an ` @Input ()` property in the child component class, receives its value from the parent's property, ` currentItem`.
When you click delete, the child component raises an event, ` deleteRequest`, which is the argument for the parent's ` crossOffItem()` method.
2020-04-28 16:26:58 -04:00
2020-10-05 17:05:28 -04:00
The following diagram shows the different parts of the ` @Input ()` and ` @Output ()` on the ` <app-input-output>` child component.
2020-04-28 16:26:58 -04:00
<div class="lightbox">
2021-03-19 16:44:28 -04:00
<img src="generated/images/guide/inputs-outputs/input-output-diagram.svg" alt="Diagram of an input target and an output target each bound to a source.">
2020-04-28 16:26:58 -04:00
</div>
2020-10-05 17:05:28 -04:00
The child selector is ` <app-input-output>` with ` item` and ` deleteRequest` being ` @Input ()` and ` @Output ()`
properties in the child component class.
The property ` currentItem` and the method ` crossOffItem()` are both in the parent component class.
2020-04-28 16:26:58 -04:00
To combine property and event bindings using the banana-in-a-box
syntax, ` [()]`, see [Two-way Binding ](guide/two-way-binding ).