Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(subjects): Rename BehaviorSubject to CurrentValueSubject, AsyncSubject to LastValueSubject #4838

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compat/AsyncSubject.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export {AsyncSubject} from 'rxjs';
export {LastValueSubject as AsyncSubject} from 'rxjs';
2 changes: 1 addition & 1 deletion compat/BehaviorSubject.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export {BehaviorSubject} from 'rxjs';
export {CurrentValueSubject as BehaviorSubject} from 'rxjs';
4 changes: 2 additions & 2 deletions compat/Rx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export {
Observer,
Subscription,
ReplaySubject,
BehaviorSubject,
CurrentValueSubject as BehaviorSubject,
Notification,
EmptyError,
ArgumentOutOfRangeError,
Expand All @@ -160,7 +160,7 @@ export {

export {TestScheduler} from 'rxjs/testing';

export { Operator, Subscriber, AsyncSubject, ConnectableObservable, TimeoutError, VirtualTimeScheduler } from 'rxjs';
export { Operator, Subscriber, LastValueSubject as AsyncSubject, ConnectableObservable, TimeoutError, VirtualTimeScheduler } from 'rxjs';
export { AjaxRequest, AjaxResponse, AjaxError, AjaxTimeoutError } from 'rxjs/ajax';

import { asapScheduler, asyncScheduler, queueScheduler, animationFrameScheduler, SchedulerLike } from 'rxjs';
Expand Down
2 changes: 1 addition & 1 deletion compat/operator/multicast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export function multicast<T, R>(SubjectFactory: (this: Observable<T>) => Subject
* source Observable. It means that all values from the source stream go through that Subject. Thus, if a Subject
* has some special properties, Observable returned by `multicast` will have them as well. If you want to use
* `multicast` with a Subject that is one of the ones included in RxJS by default - {@link Subject},
* {@link AsyncSubject}, {@link BehaviorSubject}, or {@link ReplaySubject} - simply use {@link publish},
* {@link LastValueSubject}, {@link CurrentValueSubject}, or {@link ReplaySubject} - simply use {@link publish},
* {@link publishLast}, {@link publishBehavior} or {@link publishReplay} respectively. These are actually
* just wrappers around `multicast`, with a specific Subject hardcoded inside.
*
Expand Down
4 changes: 2 additions & 2 deletions doc/decision-tree-widget/tree.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,13 @@ children:
- label: and start it manually or imperatively
children:
- label: publish
- label: using a BehaviorSubject
- label: using a CurrentValueSubject
children:
- label: publishBehavior
- label: using a ReplaySubject
children:
- label: publishReplay
- label: using an AsyncSubject
- label: using a LastValueSubject
children:
- label: publishLast
- label: using a specific subject implementation
Expand Down
26 changes: 13 additions & 13 deletions doc/subject.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ observable.subscribe(subject); // You can subscribe providing a Subject

With the approach above, we essentially just converted a unicast Observable execution to multicast, through the Subject. This demonstrates how Subjects are the only way of making any Observable execution be shared to multiple Observers.

There are also a few specializations of the `Subject` type: `BehaviorSubject`, `ReplaySubject`, and `AsyncSubject`.
There are also a few specializations of the `Subject` type: `CurrentValueSubject`, `ReplaySubject`, and `LastValueSubject`.

## Multicasted Observables

Expand Down Expand Up @@ -204,17 +204,17 @@ setTimeout(() => {

The `refCount()` operator is only available to use on ConnectableObservable, and it returns an `Observable`, not another ConnectableObservable.

## BehaviorSubject
## CurrentValueSubject

One of the variants of Subjects is the `BehaviorSubject`, which has a notion of "the current value". It stores the latest value emitted to its consumers, and whenever a new Observer subscribes, it will immediately receive the "current value" from the `BehaviorSubject`.
One of the variants of Subjects is the `CurrentValueSubject`, which has a notion of "the current value". It stores the latest value emitted to its consumers, and whenever a new Observer subscribes, it will immediately receive the "current value" from the `CurrentValueSubject`.

<span class="informal">BehaviorSubjects are useful for representing "values over time". For instance, an event stream of birthdays is a Subject, but the stream of a person's age would be a BehaviorSubject.</span>
<span class="informal">CurrentValueSubjects are useful for representing "values over time". For instance, an event stream of birthdays is a Subject, but the stream of a person's age would be a CurrentValueSubject.</span>

In the following example, the BehaviorSubject is initialized with the value `0` which the first Observer receives when it subscribes. The second Observer receives the value `2` even though it subscribed after the value `2` was sent.
In the following example, the CurrentValueSubject is initialized with the value `0` which the first Observer receives when it subscribes. The second Observer receives the value `2` even though it subscribed after the value `2` was sent.

```ts
import { BehaviorSubject } from 'rxjs';
const subject = new BehaviorSubject(0); // 0 is the initial value
import { CurrentValueSubject } from 'rxjs';
const subject = new CurrentValueSubject(0); // 0 is the initial value

subject.subscribe({
next: (v) => console.log(`observerA: ${v}`)
Expand All @@ -240,7 +240,7 @@ subject.next(3);

## ReplaySubject

A `ReplaySubject` is similar to a `BehaviorSubject` in that it can send current and new values to new subscribers, but it can also *record* a part of the Observable execution.
A `ReplaySubject` is similar to a `CurrentValueSubject` in that it can send current and new values to new subscribers, but it can also *record* a part of the Observable execution.

<span class="informal">A `ReplaySubject` records multiple values from the Observable execution and replays them to new subscribers.</span>

Expand Down Expand Up @@ -311,13 +311,13 @@ setTimeout(() => {
// ...
```

## AsyncSubject
## LastValueSubject

The AsyncSubject is a variant where only the last value of the Observable execution is sent to its observers, and only when the execution completes.
The LastValueSubject is a variant where only the last value of the Observable execution is sent to its observers, and only when the execution completes.

```ts
import { AsyncSubject } from 'rxjs';
const subject = new AsyncSubject();
import { LastValueSubject } from 'rxjs';
const subject = new LastValueSubject();

subject.subscribe({
next: (v) => console.log(`observerA: ${v}`)
Expand All @@ -340,4 +340,4 @@ subject.complete();
// observerB: 5
```

The AsyncSubject is similar to the [`last()`](../class/es6/Observable.js~Observable.html#instance-method-last) operator, in that it waits for the `complete` notification in order to deliver a single value.
The LastValueSubject is similar to the [`last()`](../class/es6/Observable.js~Observable.html#instance-method-last) operator, in that it waits for the `complete` notification in order to deliver a single value.
4 changes: 2 additions & 2 deletions docs_app/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { SearchResults } from 'app/search/interfaces';
import { SearchService } from 'app/search/search.service';
import { TocService } from 'app/shared/toc.service';

import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { CurrentValueSubject, combineLatest, Observable } from 'rxjs';
import { first, map } from 'rxjs/operators';

const sideNavView = 'SideNav';
Expand Down Expand Up @@ -70,7 +70,7 @@ export class AppComponent implements OnInit {
topMenuNarrowNodes: NavigationNode[];

hasFloatingToc = true;
private showFloatingToc = new BehaviorSubject(false);
private showFloatingToc = new CurrentValueSubject(false);
private showFloatingTocWidth = 800;
tocMaxHeight: string;
private tocMaxHeightOffset = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BehaviorSubject } from 'rxjs';
import { CurrentValueSubject } from 'rxjs';

import { ApiListComponent } from './api-list.component';
import { ApiItem, ApiSection, ApiService } from './api.service';
Expand Down Expand Up @@ -234,7 +234,7 @@ class TestLocationService {
}

class TestApiService {
sectionsSubject = new BehaviorSubject(getApiSections());
sectionsSubject = new CurrentValueSubject(getApiSections());
sections = this.sectionsSubject.asObservable();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ import {
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ScrollService } from 'app/shared/scroll.service';
import { BehaviorSubject } from 'rxjs';
import { CurrentValueSubject } from 'rxjs';
import { treeNodeStubNoOptions, treeNodeStubWithOptionsA } from './fixtures';
import { OperatorDecisionTreeComponent } from './operator-decision-tree.component';
import { OperatorDecisionTreeService } from './operator-decision-tree.service';

const operatorDecisionTreeServiceStub = {
currentSentence$: new BehaviorSubject('Conditioner is better'),
options$: new BehaviorSubject([treeNodeStubWithOptionsA]),
isBeyondInitialQuestion$: new BehaviorSubject(false),
hasError$: new BehaviorSubject(false),
currentSentence$: new CurrentValueSubject('Conditioner is better'),
options$: new CurrentValueSubject([treeNodeStubWithOptionsA]),
isBeyondInitialQuestion$: new CurrentValueSubject(false),
hasError$: new CurrentValueSubject(false),
selectOption: jasmine.createSpy(),
back: jasmine.createSpy(),
startOver: jasmine.createSpy()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs';
import { CurrentValueSubject, combineLatest, Observable, of } from 'rxjs';
import { catchError, filter, map, mapTo, shareReplay } from 'rxjs/operators';
import { OperatorDecisionTree, OperatorTreeNode, State } from './interfaces';
import { OperatorDecisionTreeDataService } from './operator-decision-tree-data.service';
Expand All @@ -11,7 +11,7 @@ export class OperatorDecisionTreeService {
previousBranchIds: ['initial'],
currentBranchId: 'initial'
};
private state$ = new BehaviorSubject<State>(this.initialState);
private state$ = new CurrentValueSubject<State>(this.initialState);
private tree$: Observable<
OperatorDecisionTree
> = this.dataService.getDecisionTree$().pipe(
Expand Down
6 changes: 3 additions & 3 deletions docs_app/src/app/custom-elements/toc/toc.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, CUSTOM_ELEMENTS_SCHEMA, DebugElement } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { asapScheduler as asap, BehaviorSubject } from 'rxjs';
import { asapScheduler as asap, CurrentValueSubject } from 'rxjs';

import { ScrollService } from 'app/shared/scroll.service';
import { TocItem, TocService } from 'app/shared/toc.service';
Expand Down Expand Up @@ -462,8 +462,8 @@ class TestScrollService {
}

class TestTocService {
tocList = new BehaviorSubject<TocItem[]>(getTestTocList());
activeItemIndex = new BehaviorSubject<number | null>(null);
tocList = new CurrentValueSubject<TocItem[]>(getTestTocList());
activeItemIndex = new CurrentValueSubject<number | null>(null);
setActiveIndex(index: number|null) {
this.activeItemIndex.next(index);
if (asap.scheduled !== undefined) {
Expand Down
4 changes: 2 additions & 2 deletions docs_app/src/app/documents/document.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';

import { AsyncSubject, Observable, of } from 'rxjs';
import { LastValueSubject, Observable, of } from 'rxjs';
import { catchError, switchMap, tap } from 'rxjs/operators';

import { DocumentContents } from './document-contents';
Expand Down Expand Up @@ -54,7 +54,7 @@ export class DocumentService {

private fetchDocument(id: string): Observable<DocumentContents> {
const requestPath = `${DOC_CONTENT_URL_PREFIX}${id}.json`;
const subject = new AsyncSubject<DocumentContents>();
const subject = new LastValueSubject<DocumentContents>();

this.logger.log('fetching document from', requestPath);
this.http
Expand Down
4 changes: 2 additions & 2 deletions docs_app/src/app/layout/top-menu/top-menu.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { BehaviorSubject } from 'rxjs';
import { CurrentValueSubject } from 'rxjs';

import { TopMenuComponent } from './top-menu.component';
import { NavigationService, NavigationViews } from 'app/navigation/navigation.service';
Expand Down Expand Up @@ -38,5 +38,5 @@ class TestNavigationService {
],
};

navigationViews = new BehaviorSubject<NavigationViews>(this.navJson);
navigationViews = new CurrentValueSubject<NavigationViews>(this.navJson);
}
4 changes: 2 additions & 2 deletions docs_app/src/testing/location.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { BehaviorSubject } from 'rxjs';
import { CurrentValueSubject } from 'rxjs';
import { map } from 'rxjs/operators';

export class MockLocationService {
urlSubject = new BehaviorSubject<string>(this.initialUrl);
urlSubject = new CurrentValueSubject<string>(this.initialUrl);
currentUrl = this.urlSubject.asObservable().pipe(map(url => this.stripSlashes(url)));
// strip off query and hash
currentPath = this.currentUrl.pipe(map(url => url.match(/[^?#]*/)![0]));
Expand Down
4 changes: 2 additions & 2 deletions spec/Subject-spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect } from 'chai';
import { hot, expectObservable } from './helpers/marble-testing';
import { Subject, ObjectUnsubscribedError, Observable, AsyncSubject, Observer, of } from 'rxjs';
import { Subject, ObjectUnsubscribedError, Observable, LastValueSubject, Observer, of } from 'rxjs';
import { AnonymousSubject } from 'rxjs/internal/Subject';
import { delay } from 'rxjs/operators';

Expand Down Expand Up @@ -508,7 +508,7 @@ describe('Subject', () => {

it('should work with inherited subject', () => {
const results: (number | string)[] = [];
const subject = new AsyncSubject<number>();
const subject = new LastValueSubject<number>();

subject.next(42);
subject.complete();
Expand Down
4 changes: 2 additions & 2 deletions spec/index-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ describe('index', () => {

it('should export the Subject types', () => {
expect(index.Subject).to.exist;
expect(index.BehaviorSubject).to.exist;
expect(index.CurrentValueSubject).to.exist;
expect(index.ReplaySubject).to.exist;
expect(index.AsyncSubject).to.exist;
expect(index.LastValueSubject).to.exist;
});

it('should export the schedulers', () => {
Expand Down
Loading