Search code examples
angularrxjs6

Communication via service isn't working Angular 8


I am working on a project where parents and children need to communicate via service. Following this article in the official documentation I am not able to make it work.

This is the service I created:

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

@Injectable()
export class CommonService {
    private _propertyChangeAnnouncedSource = new Subject<string>();
    propertyChangeAnnounced$ = this._propertyChangeAnnouncedSource.asObservable();

    public announcePropertyChange(data: string) {
        this._propertyChangeAnnouncedSource.next(data);
    }
}

In the parent component, I import all I need:

@Component({
    selector: 'app-parent',
    templateUrl: './parent.component.html',
    styleUrls: ['./parent.component.scss'],
    providers: [CommonService]
})
export class ParentComponent implements OnInit {

    constructor(private _commonService: CommonService) {

    }

    tellChild(data): void {
        this._commonService.announcePropertyChange(data);
    }

}

This is the child's code:

@Component({
    selector: 'app-child',
    templateUrl: './child.component.html',
    styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit, OnDestroy {
    private subscription: Subscription;

    constructor(private _commonService: CommonService) {
        this.subscription = this._commonService.propertyChangeAnnounced$.subscribe(
            data => {
                console.log(data);
          });
    }
}

When I call the announcePropertyChange the child is not responding. Any suggestion?

Thanks!


Solution

  • There could be several problems:

    1. Check whether or not child and parent component have the same instance of the service. You could have provided CommonService several places thus parent and child might not share same instance of the class.

    2. How do you exactly execute tellChild() method? Maybe you execute the method when the parent component is initiated, thus new event is emitted by Observable, but child has not yet created and has not subscribed to Observable, it skips the event.

    Possible solutions:

    • If problem 2 is your case then I suggest you to update your CommonService to use BehaviorSubject instead of Subject. private _propertyChangeAnnouncedSource = new BehaviorSubject<string>(null); This way no matter what time someone subscribes to the Observable they will get the latest value and continue monitoring further changes. If you want to avoid initial null value due to BehaviorSubject, I suggest you to modify Observable like so: propertyChangeAnnounced$ = this._propertyChangeAnnouncedSource.asObservable() .pipe(filter(x => x !== null));

    This is it for now, lets hear from you about these 2 and I will update my response later if there is still the problem.