Sharing Data between Angular Components

In Angular,

data sharing between components is a common requirement, and there are several ways to achieve it depending on the relationship between the components.

Sharing data between parent and child components in Angular can be achieved by using @Input and @Output decorators.

Let’s consider the following hierarchy:

<parent-component>
  <child-component></child-component>
</parent-component>

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

@Input() and @Output() decorators give a child component a way to communicate with its parent component.

@Input() decorator lets a parent component send or update data in the child component.

Similarly, @Output() decorator lets the child component send data to a parent component.

Create Angular Project

You can create Angular project using the command ng new angular-parent-child-data-share --no-standalone.

You can create a child component using the command ng generate component child.

Sharing data from parent to a child component

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

To use @Input(), you need to configure the parent and child components.

Configuring the child component

To use the @Input() decorator in a child component class, you need to first import Input and then decorate the property with @Input(), as in the following example – src/app/child/child.component.ts.

import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrl: './child.component.css'
})
export class ChildComponent {

	@Input() childMessage: string = '';





}

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. The value for item comes from the parent component.

Next, in the child component template – src/app/child/child.component.html, add the following:

<p>This is a '{{childMessage}}' in Child component</p>

Configuring the parent component

The next step is to bind the property in the parent component’s template. In this example, the parent component template is src/app/app.component.html.

Use the child’s selector, here <app-child>, as a directive within the parent component template.

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

<app-child [childMessage]="parentMessage"></app-child>

In the parent component class – src/app/app.component.ts, designate a value for parentMessage:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'Angular Pass Data from Parent to Child';
  
  parentMessage: string = 'Message from Parent';
  
}

With @Input(), Angular passes the value for parentMessage to the child so that item renders as 'Message from Parent'.

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.

Output

You will see the following output from the application:

data share between parent child components

Sharing data from child to a parent component

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

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.

The following example shows how to set up an @Output() in a child component that pushes data from an HTML to an array in the parent component.

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

Configuring the child component

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.

Import Output and EventEmitter in the child component class – src/app/child/child.component.ts.

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.

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

import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrl: './child.component.css'
})
export class ChildComponent {
	
	@Output() newItemEvent = new EventEmitter<string>();
	
	addNewItem(value: string) {
		this.newItemEvent.emit(value);
	}

}

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

Configuring the child’s template

The child’s template (src/app/child/child.component.html) has two controls. The first is an HTML <input> with a template reference variable, #newItem, where the user types in an item name. The value property of the #newItem variable stores what the user types into the <input>.

<label for="item-input">Add an item:</label>
<input type="text" id="item-input" #newItem>
<button type="button" (click)="addNewItem(newItem.value)">Add to parent's list</button>

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

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.

Configuring the parent component

The AppComponent (src/app/app.component.ts) in this example features a list of items in an array and a method for adding more items to the array.

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'Angular Pass Data from Parent to Child';
  
  items = ['item1', 'item2', 'item3', 'item4'];

  addItem(newItem: string) {
    this.items.push(newItem);
  }
  
}

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

Configuring the parent’s template

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

Put the child selector, here <app-child>, within the parent component’s template, src/app/app.component.html.

<app-child (newItemEvent)="addItem($event)"></app-child>

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

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

To see the @Output() working, add the following to the parent’s template – src/app/app.component.html:

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

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.

Output

You will see the following output:

data share between child parent components

When you input something for adding to the liste:

data share between child parent components

The final output will be:

data share between child parent components

Source Code

Download

Share

Related posts

No comments

Leave a comment