{ "id": "guide/inputs-outputs", "title": "Sharing data between child and parent directives and components", "contents": "\n\n\n
\n mode_edit\n
\n\n\n
\n

Sharing data between child and parent directives and componentslink

\n

A common pattern in Angular is sharing data between a parent component and one or more child components.\nYou can implement this pattern by using the @Input() and @Output() directives.

\n
\n

See the for a working example containing the code snippets in this guide.

\n
\n

Consider the following hierarchy:

\n\n<parent-component>\n <child-component></child-component>\n</parent-component>\n\n

The <parent-component> serves as the context for the <child-component>.

\n

@Input() and @Output() give a child component a way to communicate with its parent component.\n@Input() allows a parent component to update data in the child component.\nConversely, @Output() allows the child to send data to a parent component.

\n\n

Sending data to a child componentlink

\n

The @Input() decorator in a child component or directive signifies that the property can receive its value from its parent component.

\n
\n \"Input\n
\n

To use @Input(), you must configure the parent and child.

\n

Configuring the child componentlink

\n

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.

\n\nimport { Component, Input } from '@angular/core'; // First, import Input\nexport class ItemDetailComponent {\n @Input() item: string; // decorate the property with @Input()\n}\n\n\n

In this case, @Input() decorates the property item, which has a type of string, however, @Input() properties can have any type, such as number, string, boolean, or object.\nThe value for item comes from the parent component.

\n

Next, in the child component template, add the following:

\n\n<p>\n Today's item: {{item}}\n</p>\n\n\n

Configuring the parent componentlink

\n

The next step is to bind the property in the parent component's template.\nIn this example, the parent component template is app.component.html.

\n
    \n
  1. \n

    Use the child's selector, here <app-item-detail>, as a directive within the\nparent component template.

    \n
  2. \n
  3. \n

    Use property binding to bind the item property in the child to the currentItem property of the parent.

    \n
  4. \n
\n\n<app-item-detail [item]=\"currentItem\"></app-item-detail>\n\n\n
    \n
  1. In the parent component class, designate a value for currentItem:
  2. \n
\n\nexport class AppComponent {\n currentItem = 'Television';\n}\n\n\n

With @Input(), Angular passes the value for currentItem to the child so that item renders as Television.

\n

The following diagram shows this structure:

\n
\n \"Property\n
\n

The target in the square brackets, [], is the property you decorate with @Input() in the child component.\nThe binding source, the part to the right of the equal sign, is the data that the parent component passes to the nested component.

\n

Watching for @Input() changeslink

\n

To watch for changes on an @Input() property, you can use OnChanges, one of Angular's lifecycle hooks.\nSee the OnChanges section of the Lifecycle Hooks guide for more details and examples.

\n\n

Sending data to a parent componentlink

\n

The @Output() decorator in a child component or directive allows data to flow from the child to the parent.

\n
\n \"Output\n
\n

@Output() marks a property in a child component as a doorway through which data can travel from the child to the parent.

\n

The child component uses the @Output() property to raise an event to notify the parent of the change.\nTo 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.

\n

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.

\n

To use @Output(), you must configure the parent and child.

\n

Configuring the child componentlink

\n

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.

\n
    \n
  1. \n

    Import Output and EventEmitter in the child component class:

    \n\nimport { Output, EventEmitter } from '@angular/core';\n\n
  2. \n
  3. \n

    In the component class, decorate a property with @Output().\nThe following example newItemEvent @Output() has a type of EventEmitter, which means it's an event.

    \n\n\n@Output() newItemEvent = new EventEmitter<string>();\n\n\n\n

    The different parts of the above declaration are as follows:

    \n
      \n
    • @Output()—a decorator function marking the property as a way for data to go from the child to the parent
    • \n
    • newItemEvent—the name of the @Output()
    • \n
    • EventEmitter<string>—the @Output()'s type
    • \n
    • new EventEmitter<string>()—tells Angular to create a new event emitter and that the data it emits is of type string.
    • \n
    \n

    For more information on EventEmitter, see the EventEmitter API documentation.

    \n
  4. \n
  5. \n

    Create an addNewItem() method in the same component class:

    \n\nexport class ItemOutputComponent {\n\n @Output() newItemEvent = new EventEmitter<string>();\n\n addNewItem(value: string) {\n this.newItemEvent.emit(value);\n }\n}\n\n\n

    The addNewItem() function uses the @Output(), newItemEvent, to raise an event with the value the user types into the <input>.

    \n
  6. \n
\n

Configuring the child's templatelink

\n

The child's template has two controls.\nThe first is an HTML <input> with a template reference variable , #newItem, where the user types in an item name.\nThe value property of the #newItem variable stores what the user types into the <input>.

\n\n<label>Add an item: <input #newItem></label>\n<button (click)=\"addNewItem(newItem.value)\">Add to parent's list</button>\n\n\n

The second element is a <button> with a click event binding.

\n

The (click) event is bound to the addNewItem() method in the child component class.\nThe addNewItem() method takes as its argument the value of the #newItem.value property.

\n

Configuring the parent componentlink

\n

The AppComponent in this example features a list of items in an array and a method for adding more items to the array.

\n\nexport class AppComponent {\n items = ['item1', 'item2', 'item3', 'item4'];\n\n addItem(newItem: string) {\n this.items.push(newItem);\n }\n}\n\n\n

The addItem() method takes an argument in the form of a string and then adds that string to the items array.

\n

Configuring the parent's templatelink

\n
    \n
  1. \n

    In the parent's template, bind the parent's method to the child's event.

    \n
  2. \n
  3. \n

    Put the child selector, here <app-item-output>, within the parent component's template, app.component.html.

    \n\n<app-item-output (newItemEvent)=\"addItem($event)\"></app-item-output>\n\n\n

    The event binding, (newItemEvent)='addItem($event)', connects the event in the child, newItemEvent, to the method in the parent, addItem().

    \n

    The $event contains the data that the user types into the <input> in the child template UI.

    \n

    To see the @Output() working, you can add the following to the parent's template:

    \n\n <ul>\n <li *ngFor=\"let item of items\">{{item}}</li>\n </ul>\n\n

    The *ngFor iterates over the items in the items array.\nWhen 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.

    \n
  4. \n
\n

Using @Input() and @Output() togetherlink

\n

You can use @Input() and @Output() on the same child component as follows:

\n\n<app-input-output [item]=\"currentItem\" (deleteRequest)=\"crossOffItem($event)\"></app-input-output>\n\n\n

The target, item, which is an @Input() property in the child component class, receives its value from the parent's property, currentItem.\nWhen you click delete, the child component raises an event, deleteRequest, which is the argument for the parent's crossOffItem() method.

\n

The following diagram shows the different parts of the @Input() and @Output() on the <app-input-output> child component.

\n
\n \"Input/Output\n
\n

The child selector is <app-input-output> with item and deleteRequest being @Input() and @Output()\nproperties in the child component class.\nThe property currentItem and the method crossOffItem() are both in the parent component class.

\n

To combine property and event bindings using the banana-in-a-box\nsyntax, [()], see Two-way Binding.

\n\n \n
\n\n\n" }