Santhosh mp
Santhosh mp

Reputation: 589

Data sharing between components in Angular 6

I have created 2 components and one service as below,

component-interaction.service.ts

@Injectable()
export class ComponentInteractionService {

  public dataSubject = new BehaviorSubject<string>("Test");

  getTestData(): Observable<any> {
    return this.dataSubject.asObservable();
  }

  pustTestData(dataToPush: string): void {
    this.dataSubject.next(dataToPush);
  }
}

first.component.ts

export class FirstComponent {

  constructor(private componentInteractionService: ComponentInteractionService) { 
    componentInteractionService.getTestData().subscribe(data=> {
      console.log("Received at 1 -- " + data);
    });
  }

  sendTestData(): void {
    this.componentInteractionService.pustTestData("sending data from 1");
  }

}

second.component.ts

export class SecondComponent {

  constructor(private componentInteractionService: ComponentInteractionService) { 
    componentInteractionService.getTestData().subscribe(data=> {
      console.log("Received at 2 -- " + data);
    });
  }
}

The issue I am currently facing is

On page load both the components subscribers are being triggered, but when I push data using sendTestData() method in FirstComponent, only the subscriber in FirstComponent is being triggered. The subscriber in SecondComponent is not being triggered. What should I do for both subscribers to get triggered on pushing data using the sendTestData() method?

My Console logs are as below..

Received at 1 -- Test

Received at 2 -- Test

Received at 1 -- sending data from 1

Expected Output..

Received at 1 -- Test

Received at 2 -- Test

Received at 1 -- sending data from 1

Received at 2 -- sending data from 1

Upvotes: 3

Views: 1321

Answers (3)

Bunyamin Coskuner
Bunyamin Coskuner

Reputation: 8859

It is because you provide the same service twice in both AppComponentOne and AppComponentTwo so they both have different instances of the same service.

Empty providers array of both component and provide the service within app.module.ts

@Component({
  selector: 'app-distinct-first-component',
  template: '<button (click)="sendTestData()">Click to send Data</button>',
  providers: [ComponentService] // <= remove this line from both components
})

app.module.ts

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent, 
  FirstComponent, SecondComponent
  ],
  bootstrap:    [ AppComponent ],
  providers: [ComponentService] // <= provide it here
})
export class AppModule { }

Upvotes: 1

shrestha rohit
shrestha rohit

Reputation: 2940

 sendTestData(): void {
  this.componentInteractionService.pustTestData("sending data from 1");
  // must call the observable once after adding new data
  this.commonService.getData();
 }

You must call the observable after setting new data to the behavior subject.

Upvotes: 0

xkeshav
xkeshav

Reputation: 54016

working fine for me. check this demo console

and here is the relevant code

common.service.ts

@Injectable()
export class CommonService {

public dataSubject$: Subject<string> = new BehaviorSubject<string>("Test");

getData(): Observable<any> {
    return this.dataSubject$.asObservable();
}

setData(dataToPush: string): void{
    this.dataSubject$.next(dataToPush);
 }
}

first.component.ts

@Component({
    selector: 'app-first',
    template: `First Component data`,
})

export class FirstComponent implements OnInit {

constructor(
      private commonService: CommonService,
    ) { 

    }

    ngOnInit(){
      this.sendCommonData();
      this.getCommonData();
    }

 getCommonData () {
   this.commonService.getData().subscribe(data=> {
        console.log("Received at 1 -- " + data);
    })
 }

sendCommonData() {
    this.commonService.setData("sending data from first");
}

}

second.component.ts

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

import { CommonService } from './common.service';

@Component({
    selector: 'app-second',
    template: `Second Component data `,
})

export class SecondComponent implements OnInit {

constructor(
      private commonService: CommonService,
    ) { 

    }

    ngOnInit(){
      this.getCommonData();
    }

 getCommonData () {
   this.commonService.getData().subscribe(data=> {
        console.log("Received at 2 -- " + data);
    })
 }


}

Upvotes: 0

Related Questions