Skip to content

BehaviorSubject's breaking behaviour in RxJS 8 #12

@dariomannu

Description

@dariomannu

A BehaviorSubject is the perfect type of stream to deliver "Suspense" (display an initial value statically whilst something else is loading).

const stream = new BehaviorSubject('loading...').pipe(
  switchMap(() => fetch('/api').then(r=>r.json())
);

target.innerHTML = rml
  <div>${stream}</div>
`;

The stream can be rendered anywhere inline whilst the async request is pending.

Rendered "inline" means the current .value of a BehaviorSubject is baked straight into the HTML before it hits the page, so the initial "loading..." value can be displayed at the same exact time as the rest.

RxJS 8.x is removing access to BehaviorSubject.value when it's "piped", making it impossible to perform the async rendering above.
Currently (RxJS <= 7) we're resorting on a hack by reading BehaviorSubject.source looking for a .value, which is also not ideal. In fact, not even RxJS 7 exposes .value on a piped BehaviorSubject, but at least we have the hack.

There is a change request with RxJS. The team might need to understand there are valid cases to keep .value available.

If this can't be achieved, the "Suspense" behaviour will need to subscribe on mount and potentially losing a frame (so the "loading..." text may show up async and cause an unnecessary layout thrash.

Example Code showing the use of BehaviorSubject.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions