Sharing data between components in Angular 11 | @input, @Output, @ViewChild and Service

Sharing data between components in Angular is an essential concept. we can pass data from Parent to Child components with each other in a number of different ways, including:

  • Parent to Child: via @Input
  • Child to Parent: via @Output() and EventEmitter
  • Child to Parent: via @ViewChild
  • Unrelated Components: via a common Service

in this post, we will cover the different methods for sharing data between components in Angular 11.

How to pass data from Parent to Child by using the @Input in Angular 11.

The Sharing data between components, the parent to child component data sharing is a common use case in Angular 11. works by using the @Input() decorator to allow data to pass in the child component.

@Input () [property-name]:[property-data-type] 

Let’s consider an example where we define the ‘userName‘ property in the child component that we want to pass data from the parent component. the @Input() decorator clearly shows that the child component is expecting some value from the parent component.

Sharing data between components - input

let’s pass data from the parent component.A property [userName]= “userName” is used to pass data to a child component.

// parent component html
<div class="container">
    <h3>dashboard</h3>
</div>

<div class="user-container">
    <app-user [userName]="userName"></app-user>
</div> 

We may transfer data from a parent component to a child component using the @Input decorator provided by Angular.

// child component component
export class UserComponent implements OnInit {
  
  @Input() userName: string
  constructor() { }

  ngOnInit(): void {
  }
} 
<div>{{userName}}</div> 

How to pass data from Child to Parent by using @output decorator in Angular 11

For sharing data from child to parent we need an @output decorator. In the child component, we have to define the @output decorator. This approach is ideal when you want to emit data from the child, which can be listened to by the parent like button clicks and other user events.

@Output () [property-name] = new EventEmitter< [property-data-type]> () 

Let’s consider an example where we define the “messageEvent” property in the child component that we want to share from the child component to the parent component by using the @outout. the @Output() decorator clearly shows that the parent component is expecting some value from the child component. 

Sharing data between components - output

export class MessageComponent {
  
  // Output decorator  to notify a parent component from a child component
  @Output() messageEvent = new EventEmitter<Message>();

  constructor() { }
 
  getMessage() {

    // get data from the server or perform some action ..
    // send message notification to parent component.
    this.sendMessage();
  }
  private sendMessage() {
    this.messageEvent.next({ message: 'test message', date: new Date().toLocaleDateString() });
  }
} 

The parent component can now subscribe to this “messageEvent” that’s outputted by the child component.

<div class="container">
    <h3>dashboard</h3>
</div>
<div class="message-container">
    <app-message (messageEvent)="onMessage($event)"></app-message>
</div> 
export class DashboardComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }
  onMessage(message: Message) {
    // display message
    console.log(message)
  }
} 

How to pass data between components using service in Angular 11

Sharing data between components, When there is no relationship between components that time you should you a shared service. When you have data that should always be in sync.

public [property-name]= new BehaviorSubject(['default-value']);
public [property-name]= new Subject<Message>(); 

We create a service “MessageService” to hold the data. Because service is a singleton, all the components that inject it can share the data it contains.

export class MessageService {
  public messageSub = new Subject<Message>();
  constructor() { }

  setData(msg: Message) {
    // get data from the server or perform some action ..
    this.messageSub.next(msg)
  }
} 

The MessageBox component can now subscribe to this “messageSub” of MessageService

export class MessageBoxComponent implements OnInit {
  messageBox: Message[];

  constructor(private mesService: MessageService) {
    this.mesService.messageSub.subscribe((res: Message) => {
      this.messageBox.push(res);
    })
  }
  ngOnInit(): void {
  }
} 

How to pass data from one component to another using Viewchild

ViewChild allows the parent component to controls the child’s methods and properties, directive, DOM element inside the parent component by using the @ViewChild() decorator. it allows one component to be injected into another.

@ViewChild([child-component-name]) child 

Let’s consider an example where we define the ‘userName’ property in the child component that we want to set the value of the ‘userName‘ property from the parent component. @ViewChild gives a reference to the child component in parent components. And it sets the value of child ‘userName’ in the parent component.

Related Post

Source code available for download

The source code is available on GitHub for Sharing data between components in angular 11 | @input, @Output, @ViewChild and Service

URLhttps://github.com/decodedscript/sharing-data-between-components-in-angular

  • Post category:Angular
  • Reading time:6 mins read