How to pass data between two components in Angular 2
Asked Answered
D

8

26

I am looking for solution to pass data to another component and similarly access methods of another component in other (both are parallel components).

For example i have two components home.ts and map.ts. I get some data into map.ts and need to pass that in home.ts and vice versa.

Dufrene answered 5/9, 2016 at 7:15 Comment(2)
angular.io/docs/ts/latest/cookbook/component-communication.html covers this topic well. If this doesn't solve your problem please post the code that demonstrates what you try to accomplish, what you have tried and where you failed.Westwardly
Pass Data Between Components Using @Output, @Input And EventEmitterSpindell
O
14

Parent to Child: Sharing Data via Input This is probably the most common and straightforward method of sharing data. It works by using the @Input() decorator to allow data to be passed via the template.

Child to Parent: Sharing Data via ViewChild ViewChild allows a one component to be injected into another, giving the parent access to its attributes and functions. One caveat, however, is that child won’t be available until after the view has been initialized. This means we need to implement the AfterViewInit lifecycle hook to receive the data from the child.

Child to Parent: Sharing Data via Output() and EventEmitter Another way to share data is to emit data from the child, which can be listed to by the parent. This approach is ideal when you want to share data changes that occur on things like button clicks, form entires, and other user events.

In the parent, we create a function to receive the message and set it equal to the message variable.

In the child, we declare a messageEvent variable with the Output decorator and set it equal to a new event emitter. Then we create a function named sendMessage that calls emit on this event with the message we want to send. Lastly, we create a button to trigger this function.

The parent can now subscribe to this messageEvent that’s outputted by the child component, then run the receive message function whenever this event occurs.

Unrelated Components: Sharing Data with a Service When passing data between components that lack a direct connection, such as siblings, grandchildren, etc, you should you a shared service. When you have data that should always been in sync, I find the RxJS BehaviorSubject very useful in this situation.

You can also use a regular RxJS Subject for sharing data via the service, but here’s why I prefer a BehaviorSubject.

It will always return the current value on subscription - there is no need to call onnext It has a getValue() function to extract the last value as raw data. It ensures that the component always receives the most recent data. In the service, we create a private BehaviorSubject that will hold the current value of the message. We define a currentMessage variable handle this data stream as an observable that will be used by the components. Lastly, we create function that calls next on the BehaviorSubject to change its value.

The parent, child, and sibling components all receive the same treatment. We inject the DataService in the constructor, then subscribe to the currentMessage observable and set its value equal to the message variable.

Now if we create a function in any one of these components that changes the value of the message. when this function is executed the new data it’s automatically broadcast to all other components.

Reference: https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/

Ouzo answered 19/12, 2018 at 4:33 Comment(0)
S
58

You can transfer data using service.

Make a service that holds the data while you switch components. Below is an example.

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

@Injectable()
export class TransfereService {

  constructor(
    private router:Router,
    private companyServiceService:CompanyServiceService
  ) { }

  private data;

  setData(data){
    this.data = data;
  }

  getData(){
    let temp = this.data;
    this.clearData();
    return temp;
  }

  clearData(){
    this.data = undefined;
  }

}

Now Consider 2 components Sender and Reciever.

Senders code: This code sets the data to the service and navigates to the receiver.

import { Router } from '@angular/router';
import { TransfereService } from './services/transfer.service';

export class SenderComponent implements OnInit {         
  constructor(
    private transfereService:TransfereService,
    private router:Router) {}

  somefunction(data){
   this.transfereService.setData(data);
   this.router.navigateByUrl('/reciever');//as per router
 }
}

Reciever's Code: This code fetches the data from service and clears the data as well.

import { Router } from '@angular/router';
import { TransfereService } from './services/transfer.service';

export class RecieverComponent implements OnInit {  
 data = this.transfereService.getData();       
 constructor(
   private transfereService:TransfereService,
   private router:Router) {
      if(this.data){
        // do whatever needed
      }
      else{
        this.router.navigateByUrl('/sender');
      }
   }
}

You should check out Fireship Demo for the same. It's helpful.

Stoffel answered 18/11, 2017 at 1:15 Comment(7)
This should be the accepted answer. Most of the other answers deal with a parent component sharing to a child component; this deals with peer components sharing data.Haruspex
This should be the accepted answer. Also it was one of those that was so obvious but didn't even realise it. And it is pretty cool since any component you inject to will have the data (thanks to Singleton Instantiation) without other complicated things to do around Angular Inputs and OutputsProsimian
Thanks a lot, Abhijit. I spent a lot of time trying out. Wish I had come across your answer earlier.Peterec
This is the best answer ! very well explained, it's even better than the official documentation. Thank you !Disrelish
Can we use angular resolve to share data?Intercut
This has a downside though; when you refresh the page, you are taken back to the sender componentOrtrud
Fantastic answer! Thanks for the help.Marcusmarcy
V
18

You can use angular 2 Inputs for passing data to a component. E.g in your child class, make an input variable using angular 2 @Input decorator.

import {Component, Input} from 'angular2/core';

@Component({
  selector: 'child',
  styles: [`
  `],
  template: `
  `
})
export class ChildComponent {
  @Input() valueToPass = 0;
}

In your parent component (i.e in which you are calling your child component, pass your parameter as follows:

<child [valueToPass] = "value"></child>

I recommend you reading this article on passing and receiving arguments between components (https://toddmotto.com/passing-data-angular-2-components-input).

Vive answered 5/9, 2016 at 8:35 Comment(0)
O
14

Parent to Child: Sharing Data via Input This is probably the most common and straightforward method of sharing data. It works by using the @Input() decorator to allow data to be passed via the template.

Child to Parent: Sharing Data via ViewChild ViewChild allows a one component to be injected into another, giving the parent access to its attributes and functions. One caveat, however, is that child won’t be available until after the view has been initialized. This means we need to implement the AfterViewInit lifecycle hook to receive the data from the child.

Child to Parent: Sharing Data via Output() and EventEmitter Another way to share data is to emit data from the child, which can be listed to by the parent. This approach is ideal when you want to share data changes that occur on things like button clicks, form entires, and other user events.

In the parent, we create a function to receive the message and set it equal to the message variable.

In the child, we declare a messageEvent variable with the Output decorator and set it equal to a new event emitter. Then we create a function named sendMessage that calls emit on this event with the message we want to send. Lastly, we create a button to trigger this function.

The parent can now subscribe to this messageEvent that’s outputted by the child component, then run the receive message function whenever this event occurs.

Unrelated Components: Sharing Data with a Service When passing data between components that lack a direct connection, such as siblings, grandchildren, etc, you should you a shared service. When you have data that should always been in sync, I find the RxJS BehaviorSubject very useful in this situation.

You can also use a regular RxJS Subject for sharing data via the service, but here’s why I prefer a BehaviorSubject.

It will always return the current value on subscription - there is no need to call onnext It has a getValue() function to extract the last value as raw data. It ensures that the component always receives the most recent data. In the service, we create a private BehaviorSubject that will hold the current value of the message. We define a currentMessage variable handle this data stream as an observable that will be used by the components. Lastly, we create function that calls next on the BehaviorSubject to change its value.

The parent, child, and sibling components all receive the same treatment. We inject the DataService in the constructor, then subscribe to the currentMessage observable and set its value equal to the message variable.

Now if we create a function in any one of these components that changes the value of the message. when this function is executed the new data it’s automatically broadcast to all other components.

Reference: https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/

Ouzo answered 19/12, 2018 at 4:33 Comment(0)
S
9

Passing data between components is a two way process. In your case, let's say home.ts contains an object named as data.

1.In the home.component.html , where you used <map-component></map-component>, replace it with <map-component [data]="data"></map-component>.

2.In the map.ts file,add the inputs like as:

@Input() data: string;
  1. Now you can use it in your code like as <p>{{data.title}}</p>

Hope it helps!

Sunward answered 23/12, 2016 at 15:40 Comment(1)
It is not recommended not to use inputs:[data] like this just use @Input() data:any refer to angular.io/docs/ts/latest/guide/style-guide.html#!#05-12Longbow
K
4

Use sessionStorage, in angular where you want to set data write it as

sessionStorage.setItem("key","value");

if you want to store your object then write as

sessionStorage.setItem("key", JSON.stringify(obj));

then the component where you want to get the value right sessionStorage.getItem("key") or for whole object JSON.parse(sessonStorage.getKey("key");

Kaminski answered 25/7, 2017 at 20:53 Comment(1)
No doubt that this approach would be work, but data remains visible and vulnerable to change. In-case someone changes the JSON structure the, Application would crash.Stoffel
V
1

In Angular2 you can communicate between two components by passing object in html.

Example

home.html:

...
<map_selector [ObjectInMap]="ObjectInHome" ></map_selector>
...
Vaughan answered 5/9, 2016 at 8:4 Comment(0)
M
0

In Angular 4 use @Input to share an object between parent and child. Here, changes to either megmor (in the parent), or radfal (in the child), will be reflected in the other.

Parent html:

<div>   
  <zoptil [radfal]="megmor"></zoptil>
  {{megmor.pergal}}
</div>

Parent ts:

let megmor = new Kreven();
this.megmor.pergal = "warbar";

Child html:

<div>
  <h2>{{radfal.pergal}}</h2>
  <label>Peragl: </label>
  <input [(ngModel)]="radfal.pergal" />
</div>

Child ts:

@Input() radfal: Kreven;
Middaugh answered 14/10, 2017 at 3:14 Comment(0)
I
0

In Angular you could use @Input to share data between components. First you should import input from @angular/core :

import { input } form '@angular/core';

and then in the component class add @input before the variable that you want to pass:

@input() variableName;
Insolvent answered 8/6, 2020 at 16:32 Comment(1)
It depends on the relation between the components. We use the @input decorator when we have parent-child relation. When the components are unrelated we use the shared service method which saved my life lately :D .Disrelish

© 2022 - 2024 — McMap. All rights reserved.