3

Sorry for my English. I have service that provide in main module. When did happen change this.userSettings object using setSettings method I want that all subscribers on userSettingsObservable were called. Subscription happens in different components through call getSettingsObservable method in this service.

    constructor() {
        this.userSettingsObservable =  new Observable((observer: Observer<UserSettings>) => {
            this.userSettingsObserver = observer;
        });
    }

    getSettingsObservable() {
        return this.userSettingsObservable;
    }

    setSettings(path: string) {
        this.userSettings = _.set(this.userSettings, path, value);
        this.userSettingsObserver.next(_.clone(this.userSettings));
    }

Examples of subscription on Observable in component:

ngOnInit() {        
    this.userSettingsService.getSettingsObservable().subscribe(
        (userSettings) => {
            this.userSettings = userSettings;
        }
    );
}

In my case subscribe calling only on last subscribed component. How to make that subscribe calling in all components where I done subscribe?

Thanks!

P.S. You can see full code of service here: https://github.com/pakhuta/siarhei.pakhuta.angular2/blob/master/src/app/shared/user-settings.service.ts#L41

and subscription here: https://github.com/pakhuta/siarhei.pakhuta.angular2/blob/master/src/app/weather/weather.component.ts#L43

SIARHEI PAKHUTA
  • 175
  • 2
  • 12
  • The problem is not clear. Is the issue when you userSettingObserver.next that not all subscribers get the value? – swestner Jan 05 '17 at 18:48
  • Yes you are right. I have several components where I done subscription. If I set breackpoint in Chrome developer console that only in one (last subscribed) component script execution stops. – SIARHEI PAKHUTA Jan 05 '17 at 18:54
  • Are you injecting or importing the service? – swestner Jan 05 '17 at 19:07
  • Also, where are you calling setSettings from? – swestner Jan 05 '17 at 19:13
  • Are you injecting or importing the service? I don't know how it correctly called. In components I writing this: constructor(private userSettingsService: UserSettingsService) setSettings I calling in components, for example when user click on item in settings menu – SIARHEI PAKHUTA Jan 05 '17 at 19:17

1 Answers1

1

My guess is that it is a timing issue, and that the observable is completing before the other components have subscribed.

The easiest solution would to be to use a BehaviorSubject or ReplaySubject instead of a regular observable.

constructor() {
        this.userSettingsObservable =  new ReplaySubject(1);//will only broadcast the last value when subscribed to
    }

And then :

this.userSettingsObservable.onNext(settings)
swestner
  • 1,881
  • 15
  • 19
  • Thanks, I try it tomorrow – SIARHEI PAKHUTA Jan 05 '17 at 21:35
  • You were right. It's a great decision. I used: this.userSettingsObservable = new BehaviorSubject(this.userSettings); this.userSettingsObservable.next(_.clone(this.userSettings)); – SIARHEI PAKHUTA Jan 08 '17 at 10:26
  • Generally subjects are frowned upon, as they 'are little pockets of evil state' to paraphrase the author of rxjs. That being said, sometimes they are unavoidable. – swestner Jan 08 '17 at 14:25