1

I am trying to communicate between 2 components. Filter component is trying to send a message to result component through service http-service.

I am able to send message to service http-service but not able to receive message in result service even though I subscribed. Here is the code

view.module.ts

@NgModule({
declarations: [FilterComponent, ResultComponent],
imports: [
CommonModule,
FormsModule,
AgGridModule.withComponents(
    []
)
})

httpService

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

@Injectable({
providedIn: 'root'
})

export class HttpServiceService {

    private subject = new Subject<any>();

    sendMessage(message: string) {
            this.subject.next({ text: message });
     }

    clearAnswers() {
        this.subject.next();
    }

    getMessage(): Observable<any> {
      return this.subject.asObservable();
    }
}

filter.component.ts

import{Component, OnInit}from '@angular/core';
import {HttpServiceService}from '../http-service.service';

@Component({
selector: 'app-filter',
templateUrl: './filter.component.html',
styleUrls: ['./filter.component.css'],
providers: [ HttpServiceService ]
})

export class FilterComponent implements OnInit {

constructor(private httpService:HttpServiceService) { }


  onFormSubmit() {
    this.httpService.sendMessage('Form submitted');
  }

}

result.component.ts

import{Component, OnDestroy}from '@angular/core';
import {Subscription}from 'rxjs';
import {GridOptions}from "ag-grid-community";
import {HttpServiceService}from '../http-service.service';

@Component({
selector: 'app-result',
templateUrl: './result.component.html',
styleUrls: ['./result.component.css'],
providers: [ HttpServiceService ]

})

export class ResultComponent implements OnInit {

message : any;
subscription: Subscription;

constructor(private httpService: HttpServiceService) {
        // subscribe to home component messages
        this.subscription = this.httpService.getMessage().subscribe(message => {console.log(message);  });
    }

    ngOnDestroy() {
        // unsubscribe to ensure no memory leaks
        this.subscription.unsubscribe();
    }
}
user1298426
  • 3,467
  • 15
  • 50
  • 96
  • is the result component instantiated at the same time as the filter component? If you used a behaviour subject the subject would recall the last emition when result later subscribed, but a simple subject will only emit to already subscribed Observers. Also make sure you are using a singleton service. – Nuno Sousa Jan 12 '19 at 18:40

1 Answers1

2

you're providing the service in 3 different places, once in root and again at each component... remove the service from the provider arrays in the components and this will work.

Every place you provide a service gives a new copy of that service to any component that injects in that part of the component tree. Sometimes this is desired, sometimes it isn't. In this case it seems like it's not what you want. If you did want multiple independent result / filter components not sharing a single service, you'd likely have to rethink your page structure or create some encapsulating component or directive to provide the service.

bryan60
  • 28,215
  • 4
  • 48
  • 65
  • Provided he changes the subject type to replaySubject or behaviourSubject or both components are active at the same time (else subject will not emit when resultComponent subscribes) – Nuno Sousa Jan 12 '19 at 18:45
  • really depends on the page structure and the timing... may not be needed or wanted. Can't really be sure from the information provided... but since the message seems to get sent on a form submission, I'd assume this isn't the problem. – bryan60 Jan 12 '19 at 19:00
  • If he the components are not **both** members of the same template I would wager it would fail. – Nuno Sousa Jan 12 '19 at 19:55
  • Nice answer! I had the same problem since yesterday and today I'm freeeeeeeeeeeeeeeeeeeeeeeeeeeeee! Thanks a lot! – Herval NGANYA May 24 '21 at 09:34