Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I share data between sibling components in angular?

Tags:

angular

I have an Angular application with 3 sibling components, they are able to access and update the variable "data". They are connected to the router, but the data I want to pass is sensitive (api endpoints to determine discounts) so I cannot use cmp2/:data

Component 1 has an object called data and Components 2 and 3 need to receive this data object. I think this can be done with a shared service, but I'm not quite sure how to get this event emitter to work..

My index.html:

<router-outlet></router-outlet>

Component 1:

<button [routerLink]=['cmp2/']>Go to Comp 2 </button>
<button [routerLink]=['cmp3/']>Go to Comp 3 </button>

Components 2 and 3:

{{ data }}
like image 501
Moshe Avatar asked May 12 '17 14:05

Moshe


People also ask

How do you implement communication between sibling components in Angular?

Sharing data between sibling components: Sharing data between siblings can be done by using points 1 and 2. First share data between the child to parent using output decorator and EventEmitter. Once received data in parent component share it to another child component using Input decorator.

How can I share data from one component to another component?

For passing the data from the child component to the parent component, we have to create a callback function in the parent component and then pass the callback function to the child component as a prop. This callback function will retrieve the data from the child component.

Can we send data from one component to another in Angular?

When we build components in an application, we maybe need to share or send data from parent to child or without a direct connection. Angular provides different these ways to communicate components: Using Input() and Output() decorators. Using Viewchild decorator.


1 Answers

As it looks like you are looking to redirect to those components, what you can do is have an event emitter on component one, that on click will emit the data to the parent(of all 3). Then in the parent you would catch the emit, and assign that to data that you pass into the other components.

Component1

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

@Component(...)
export class Component1 {
    @Output() redirect:EventEmitter<any> = new EventEmitter();

    data:any = {text: "example"};

    constructor(private router:Router){}

    changeComponent(url:string){
        this.redirect.emit(data);//emits the data to the parent
        this.router.navigate([url]);//redirects url to new component
    }
}

Component2 & Component3

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

@Component(...)
export class Component2 {
    @Input() data:any;
}

Parent

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

@Component(...)
export class Parent {
    parentData:any;
}

Parent.html

<component1 (redirect)="parentData=$event"></component1>
<component2 [data]="parentData"></component2>
<component3 [data]="parentData"></component3>

Another option, if you don't have a parent, is to have a service, that you inject into each parent, and then for the receivers hook into the OnInit lifecycle hook. This works because services are a singleton if in a provider of a shared module.

Service

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

@Injectable()
export class SharingService{
    private data:any = undefined;

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

    getData():any{
        return this.data;
    }
}

Component1

import { Component }      from '@angular/core';
import { Router }         from '@angular/router';
import { SharingService } form './sharing.service';

@Component(...)
export class Component1 {

    data:any = {text: "example"};

    constructor(private router:Router,
        private sharingService:SharingService){}

    changeComponent(url:string){
        this.sharingService.setData(this.data);
        this.router.navigate([url]);//redirects url to new component
    }
}

Component2 & Component3

import { Component, OnInit } from '@angular/core';
import { SharingService }    form './sharing.service';

@Component(...)
export class Component2 implements OnInit{
    data:any;

    constructor(private router:Router,
        private sharingService:SharingService){}

    ngOnInit(){
        this.data = this.sharingService.getData();
    }
}

Make sure you add it to providers array of the module.

Module

import { SharingService } from './sharing.service';
...

@NgModule({
    ...
    providers: [ SharingService ]
})
like image 161
Joo Beck Avatar answered Sep 19 '22 23:09

Joo Beck