Sharing Data between components in Angular with three easy cases

 case:1 Sharing data From parent to child.

    Here we are sending the message to child component form parent component using @Input() decorator

    App.component.ts (Parent component) 

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

    @Component({
     selector: 'my-app',
     templateUrl: './app.component.html',
    styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
     name = 'Angular';
    message="welcome to CodingWithart" //write the message u want to send to the child
    }

App.component.html
<p>
  <app-child [data]="message"></app-child>
</p>


Here in App.component.html ,we bind the data through Property Binding in the HTML tag of Child component. Here child expects the property named "data" whose value is stored in "message" variable


child.component.ts (child component)
import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Input() data: any 
  constructor() { }

  ngOnInit() {
  }

}

Now at child component define @Input() decorator to receive data from parent component.

Note: The data which we have used in app.component.ts for property binding should be used here as input decorator with same name.

Html part of Child Component.

child.component.html
<div>
  Parent sending {{data}}
</div>

Here we have used string interpolation to print the data

I have attached screenshot to see the output of the above code.
 

case:2 Sharing Data from child to parent

We send data from Child to Parent using @Output decorator and EventEmitter.
1.We first import Output and EventEmitter from @angular/core.
2.Then write the message to be sent to the parent .
3.Create a property named "event" of class EventEmitter through which we will send data to parent and decorate with an output decorator
4.Create a method which will be called when a button is clicked.

child.component.ts
  import { Component, Input, OnInit ,Output,EventEmitter} from '@angular/core';

  @Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
  })
  export class ChildComponent implements OnInit {
  message="we are CodingWithArt"
  @Output() event=new EventEmitter<any>()
  constructor() { }

  ngOnInit() {
  }
  SendMessageToParent() 
  {
    this.event.emit(this.message)
  }
}
  

We create button in html file so that when it is clicked the data is sent to parent component

child.component.html

    <div>
    <button (click)="SendMessageToParent()">click me</button> 
    </div>

Here we bind the click event to the button to call the method "SendMessageToParent()".

In our parent component(app.component.ts) we create a method "receiveMessageFromChild()" to receive the message from child.

app.component.ts

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

  @Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
  })
  export class AppComponent  {
  name = 'Angular';
  receivedDataFromChild:any
  receiveMessageFromChild(event:any)
  {
    this.receivedDataFromChild=event
  }
  }

  

In the html file of Parent component, we bind our custom event in the selector of child component.

app.component.html

  <div>
  <h1> message from child {{receivedDataFromChild}}</h1>
  <app-child (event)="receiveMessageFromChild($event)"></app-child>
  </div>

  

When the event is received by parent,it will call the "receiveMessageFromChild($event)" method.We display the message received from child using interpolation.

Before Clicking the button


After Click of Button'"Click me"


case 3: Sharing data between unrelated component like siblings, grandchidren,etc via service.

Here  we use a regular Rxjs subject to send data via service. There are two components sender.component.ts and receiver.component.ts and they are unrelated to each other .So we send data through service called data.service.ts .

Steps:

1.First create two components sender.component.ts and receiver.component.ts and then go to
  app.module.ts
  import { NgModule } from '@angular/core';
  import { BrowserModule } from '@angular/platform-browser';
  import { FormsModule } from '@angular/forms';

  import { AppComponent } from './app.component';
  import { SenderComponent } from './sender/sender.component';
  import { ReceiverComponent } from './receiver/receiver.component';
  import { DataService } from './data.service';

@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent,SenderComponent,ReceiverComponent],
  bootstrap: [AppComponent],
  providers:[DataService]
})
export class AppModule {}

  
to declare those component(declarations:[AppComponent,SenderComponent,ReceiverComponent],)

2. create a service called data.service.ts and then go to app.module.ts to keep it in the providers array(providers:[DataService])
here is the example .
app.module.ts

3. Include those selectors in app.component.html.
  <app-sender></app-sender>
  <app-receiver></app-receiver>
  <p>
  Start editing to see some magic happen :){{name}}
  </p>
app.component.ts 
  import { Component } from '@angular/core';

  @Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
  })
  export class AppComponent  {
  name = 'Angular';
  }

4. In the service file we create private regular subject. We save the value of data sent by sender in the observable.

data.service.ts

    import { Injectable } from '@angular/core';
    import { Subject } from 'rxjs';

    @Injectable()
    export class DataService {
    private sendmsg =new Subject();//create a regular subject to store the data sent by sender
    sendMsg$=this.sendmsg.asObservable()
    
    constructor() { }
    getmsg(data:any)
    {
      this.sendmsg.next(data)//stores the data in the observable
    }
    }
  

5.We send the data from sender.component.ts by calling the function in the data.service.ts. We inject dataservice in the constructor and import dataservice.

sender.component.ts

    import { Component, OnInit } from '@angular/core';
    import { DataService } from '../data.service';

    @Component({
    selector: 'app-sender',
    templateUrl: './sender.component.html',
    styleUrls: ['./sender.component.css']
    })
    export class SenderComponent implements OnInit {
    message:any
    constructor(private dataService:DataService) { }
    ngOnInit() {
     this.sendData()
    }
    sendData()
    {
      this.message="we are CodingWithArt";
      this.dataService.getmsg(this.message);//sends the data 
    }
    }
  

sender.component.html

    <p>
    I am from sender
    </p>
  

6.We subscribe the receiver.component.ts file and get the data from sender .We inject dataservice in the constructor and import dataservice and then subscribe the observable and set the value of the receiver as res .

 receiver.component.ts 

    import { Component, OnInit } from '@angular/core';
    import { Subject } from 'rxjs';
    import { takeUntil } from 'rxjs/operators';
    import { DataService } from '../data.service';

    @Component({
    selector: 'app-receiver',
    templateUrl: './receiver.component.html',
    styleUrls: ['./receiver.component.css']
    })
    export class ReceiverComponent implements OnInit {
    private ngUnsubscribe=new Subject()
    receive:any
    constructor(private dataService:DataService) { 
      this.detectmsg()
    }

    ngOnInit() {
    }
    detectmsg(){
      this.dataService.sendMsg$.pipe(takeUntil(this.ngUnsubscribe)).subscribe((res:any)=>{
        this.receive=res;
      })
    }
    }
  

receiver.component.html

    <p>
    Hi {{receive}}
    </p>
  

Here is the final result of the data sent by sender and received by receiver.


Here is the link of Stackblitz . You can visit : stackblitzlink