11

I want to write a simple toggle inside an Angular2 service.

Therefore I need the current value of a Subject I observe (see below).

import {Injectable} from 'angular2/core';
import {Subject} from 'rxjs/Subject';

@Injectable()

export class SettingsService {

  private _panelOpened = new Subject<boolean>();
  panelOpened$ = this._panelOpened.asObservable();

  togglePanel() {
    this._panelOpened.next(!this.panelOpened$);
  }

}

How do I get the current value from _panelOpened/panelOpened$?

Thanks.

isherwood
  • 58,414
  • 16
  • 114
  • 157
Sommereder
  • 904
  • 4
  • 10
  • 32

2 Answers2

14

Seems you are looking for BehaviorSubject

private _panelOpened = new BehaviorSubject<boolean>(false);

If you subscribe you get the last value as first event.

togglePanel() {
  this.currentValue = !this.currentValue;
  this._panelOpened.next(this.currentValue);
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    Subject or BehaviorSubject shouldn't matter in this case. I know how to subscribe, but **isn't there a way to get the value without a subscription?** A bit of an overload to subscribe / unsubscribe each time I simply want the current value... The subscription is more to get notified when the value changes - as I see it. – Sommereder Mar 15 '16 at 14:34
  • Just assign the last value to a local field. – Günter Zöchbauer Mar 15 '16 at 14:34
  • 1
    That's simple, you don't. An `Observable` doesn't keep a value. When it receives one, it forwards it to subscribers and drops it. Some special operators and `BehaviorSubject` maintain a state, but there are no means of accessing it besides subscribing. – Günter Zöchbauer Mar 15 '16 at 14:41
  • 4
    BehaviorSubject actually does expose its current value through an instance method named "getValue"; it is not necessary to subscribe to obtain it. – Matt Burnell Mar 16 '16 at 08:05
4

To elaborate on @MattBurnell in the comments of the accepted answer;

If you just want the current value right now (and you don't want a lot of subscriptions floating around), you can just use the method getValue() of the BehaviorSubject.

import {Component, OnInit} from 'angular2/core';
import {BehaviorSubject} from 'rxjs/subject/BehaviorSubject';

@Component({
  selector: 'bs-test',
  template: '<p>Behaviour subject test</p>'
})
export class BsTest implements OnInit {

  private _panelOpened = new BehaviorSubject<boolean>(false);
  private _subscription;

  ngOnInit() {
    console.log('initial value of _panelOpened', this._panelOpened.getValue());

    this._subscription = this._panelOpened.subscribe(next => {
      console.log('subscribing to it will work:', next);
    });

    // update the value:
    console.log('==== _panelOpened is now true ====');
    this._panelOpened.next(true);

    console.log('getValue will get the next value:', this._panelOpened.getValue());
  }
}

This will result in:

initial value of _panelOpened false
subscribing to it will work: false
==== _panelOpened is now true ====
subscribing to it will work: true
getValue will get the next value: true

See plunker:

rnacken
  • 171
  • 5