3
votes

I'm trying to create a shared service to communicate between components using an Observable, using: http://blog.angular-university.io/how-to-build-angular2-apps-using-rxjs-observable-data-services-pitfalls-to-avoid/ as a guide:

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


@Injectable()
export class ModalService {

  private _isOpen: BehaviorSubject<boolean> = new BehaviorSubject(false);
  public isOpen: Observable<boolean> = this._isOpen.asObservable();


  openModal() {
    this._isOpen.next(true);
  }

  closeModal() {
    this._isOpen.next(false);
  }

}

in my component(s), I subscribe to isOpen, which receives a value when subscribing:

. . .

  ngOnInit(): void {
    this.subscription = this.modalService.isOpen.subscribe(state => {
      console.log('`isOpen` in subscription', state);
    });
  }

However, when I trigger .openModal() on the shared service instance, the subscriber never receives the new value. What am I doing wrong?

My logic was that by using a Behavior Subject, the subscriber would receive an initial value of false, then I could change the value on click from other components that have an instance of the shared service.

1
next was deprecated, try with this._isOpen.emit(true) - dlcardozo
TypeScript is telling me: Property 'emit' does not exist on type BehaviorSubject - Brandon Taylor
My bad, next it's fine there, it was deprecated on EventEmitter. It seems to be a DI issue, you added the modalService on your main ngModule as a provider right? - dlcardozo
I don't get it. My use case is identical to: stackoverflow.com/questions/36715918/… and it seems to be working for that user. - Brandon Taylor
If I call: this.modalService.openModal(); in the component where I subscribe to isOpen, it works. If I call the same method from another component with the modalService injected into it, and call .openModal() it doesn't work. - Brandon Taylor

1 Answers

7
votes

My application has several sub-modules, and a shared module to register common components, and modules between them. I had registered the ModalService in the shared component.

I moved the ModalService to the Providers of the uppermost (app.module.ts) providers array, and it works as expected.

Thanks to @camaron for the tip. Note to self: never, ever register a provider in a shared module :)