3
votes

Is there a simpler way to get the latest value of a subject, perform some modification and broadcast the changed value?

This is how I currently do it:

private currentMonthStream: Subject<Moment>; 

private goNextMonth() {
    this.currentMonthStream.first().subscribe((currentMonth) => {
        this.currentMonthStream.next(currentMonth.add(1, 'months'));
    });
}

Edit: It occurs to me that this really would only make sense for ReplaySubject and BehaviorSubject and have opted to creating my own implementation of ReplaySubject that can do this easily:

export class StreamSubject<T> extends ReplaySubject<T> {

    constructor() {
        super(1);
    }

    update(fn: (val: T) => T) {
        this.first().subscribe((val) => {
            this.next(fn(val));
        });
    }
}

However, since I'm still new to rx, is there something wrong with needing a function like this?

1

1 Answers

0
votes

With a normal subject (i.e. created by new Rx.Subject()), as a subject is also an observable, you could also use withLatestFrom (don-t know if it made it to Rxjs v5 beta yet) to get the latest value of the subject. To emit a new value, you use next or onNext depending on the version of Rx you are using.

Is there a simpler way?

There might be other ways, including ways which uses a subject for signalling rather than for holding values, it is arguable whether that would be simpler.

I'm still new to rx, is there something wrong with needing a function like this?

The question calls for opinionated and subjective answers. That said, there is a general advice to use subject as a last resort (could be a hard read though): http://davesexton.com/blog/post/To-Use-Subject-Or-Not-To-Use-Subject.aspx.

So I would transform your question into : Is there a way to achieve this feature without using subject? Sometimes you can, sometimes you can't.